diff options
Diffstat (limited to 'sleekxmpp/xmlstream/handler')
-rw-r--r-- | sleekxmpp/xmlstream/handler/base.py | 85 | ||||
-rw-r--r-- | sleekxmpp/xmlstream/handler/callback.py | 82 | ||||
-rw-r--r-- | sleekxmpp/xmlstream/handler/waiter.py | 93 |
3 files changed, 112 insertions, 148 deletions
diff --git a/sleekxmpp/xmlstream/handler/base.py b/sleekxmpp/xmlstream/handler/base.py index 7f05c757..59dcb306 100644 --- a/sleekxmpp/xmlstream/handler/base.py +++ b/sleekxmpp/xmlstream/handler/base.py @@ -1,9 +1,12 @@ +# -*- coding: utf-8 -*- """ - SleekXMPP: The Sleek XMPP Library - Copyright (C) 2010 Nathanael C. Fritz - This file is part of SleekXMPP. + sleekxmpp.xmlstream.handler.base + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - See the file LICENSE for copying permission. + Part of SleekXMPP: The Sleek XMPP Library + + :copyright: (c) 2011 Nathanael C. Fritz + :license: MIT, see LICENSE for more details """ import weakref @@ -16,78 +19,62 @@ class BaseHandler(object): incoming stanzas so that the stanza may be processed in some way. Stanzas may be matched with multiple handlers. - Handler execution may take place in two phases. The first is during - the stream processing itself. The second is after stream processing - and during SleekXMPP's main event loop. The prerun method is used - for execution during stream processing, and the run method is used - during the main event loop. - - Attributes: - name -- The name of the handler. - stream -- The stream this handler is assigned to. - - Methods: - match -- Compare a stanza with the handler's matcher. - prerun -- Handler execution during stream processing. - run -- Handler execution during the main event loop. - check_delete -- Indicate if the handler may be removed from use. + Handler execution may take place in two phases: during the incoming + stream processing, and in the main event loop. The :meth:`prerun()` + method is executed in the first case, and :meth:`run()` is called + during the second. + + :param string name: The name of the handler. + :param matcher: A :class:`~sleekxmpp.xmlstream.matcher.base.MatcherBase` + derived object that will be used to determine if a + stanza should be accepted by this handler. + :param stream: The :class:`~sleekxmpp.xmlstream.xmlstream.XMLStream` + instance that the handle will respond to. """ def __init__(self, name, matcher, stream=None): - """ - Create a new stream handler. - - Arguments: - name -- The name of the handler. - matcher -- A matcher object from xmlstream.matcher that will be - used to determine if a stanza should be accepted by - this handler. - stream -- The XMLStream instance the handler should monitor. - """ + #: The name of the handler self.name = name + + #: The XML stream this handler is assigned to + self.stream = None if stream is not None: self.stream = weakref.ref(stream) - else: - self.stream = None + stream.register_handler(self) + self._destroy = False self._payload = None self._matcher = matcher - if stream is not None: - stream.registerHandler(self) def match(self, xml): - """ - Compare a stanza or XML object with the handler's matcher. + """Compare a stanza or XML object with the handler's matcher. - Arguments - xml -- An XML or stanza object. + :param xml: An XML or + :class:`~sleekxmpp.xmlstream.stanzabase.ElementBase` object """ return self._matcher.match(xml) def prerun(self, payload): - """ - Prepare the handler for execution while the XML stream is being - processed. + """Prepare the handler for execution while the XML + stream is being processed. - Arguments: - payload -- A stanza object. + :param payload: A :class:`~sleekxmpp.xmlstream.stanzabase.ElementBase` + object. """ self._payload = payload def run(self, payload): - """ - Execute the handler after XML stream processing and during the + """Execute the handler after XML stream processing and during the main event loop. - Arguments: - payload -- A stanza object. + :param payload: A :class:`~sleekxmpp.xmlstream.stanzabase.ElementBase` + object. """ self._payload = payload def check_delete(self): - """ - Check if the handler should be removed from the list of stream - handlers. + """Check if the handler should be removed from the list + of stream handlers. """ return self._destroy diff --git a/sleekxmpp/xmlstream/handler/callback.py b/sleekxmpp/xmlstream/handler/callback.py index 7fadab43..37f53335 100644 --- a/sleekxmpp/xmlstream/handler/callback.py +++ b/sleekxmpp/xmlstream/handler/callback.py @@ -1,9 +1,12 @@ +# -*- coding: utf-8 -*- """ - SleekXMPP: The Sleek XMPP Library - Copyright (C) 2010 Nathanael C. Fritz - This file is part of SleekXMPP. + sleekxmpp.xmlstream.handler.callback + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - See the file LICENSE for copying permission. + Part of SleekXMPP: The Sleek XMPP Library + + :copyright: (c) 2011 Nathanael C. Fritz + :license: MIT, see LICENSE for more details """ from sleekxmpp.xmlstream.handler.base import BaseHandler @@ -18,48 +21,42 @@ class Callback(BaseHandler): The handler may execute the callback either during stream processing or during the main event loop. - Callback functions are all executed in the same thread, so be - aware if you are executing functions that will block for extended - periods of time. Typically, you should signal your own events using the - SleekXMPP object's event() method to pass the stanza off to a threaded - event handler for further processing. - - Methods: - prerun -- Overrides BaseHandler.prerun - run -- Overrides BaseHandler.run + Callback functions are all executed in the same thread, so be aware if + you are executing functions that will block for extended periods of + time. Typically, you should signal your own events using the SleekXMPP + object's :meth:`~sleekxmpp.xmlstream.xmlstream.XMLStream.event()` + method to pass the stanza off to a threaded event handler for further + processing. + + + :param string name: The name of the handler. + :param matcher: A :class:`~sleekxmpp.xmlstream.matcher.base.MatcherBase` + derived object for matching stanza objects. + :param pointer: The function to execute during callback. + :param bool thread: **DEPRECATED.** Remains only for + backwards compatibility. + :param bool once: Indicates if the handler should be used only + once. Defaults to False. + :param bool instream: Indicates if the callback should be executed + during stream processing instead of in the + main event loop. + :param stream: The :class:`~sleekxmpp.xmlstream.xmlstream.XMLStream` + instance this handler should monitor. """ def __init__(self, name, matcher, pointer, thread=False, once=False, instream=False, stream=None): - """ - Create a new callback handler. - - Arguments: - name -- The name of the handler. - matcher -- A matcher object for matching stanza objects. - pointer -- The function to execute during callback. - thread -- DEPRECATED. Remains only for backwards compatibility. - once -- Indicates if the handler should be used only - once. Defaults to False. - instream -- Indicates if the callback should be executed - during stream processing instead of in the - main event loop. - stream -- The XMLStream instance this handler should monitor. - """ BaseHandler.__init__(self, name, matcher, stream) self._pointer = pointer self._once = once self._instream = instream def prerun(self, payload): - """ - Execute the callback during stream processing, if - the callback was created with instream=True. - - Overrides BaseHandler.prerun + """Execute the callback during stream processing, if + the callback was created with ``instream=True``. - Arguments: - payload -- The matched stanza object. + :param payload: The matched + :class:`~sleekxmpp.xmlstream.stanzabase.ElementBase` object. """ if self._once: self._destroy = True @@ -67,16 +64,13 @@ class Callback(BaseHandler): self.run(payload, True) def run(self, payload, instream=False): - """ - Execute the callback function with the matched stanza payload. - - Overrides BaseHandler.run + """Execute the callback function with the matched stanza payload. - Arguments: - payload -- The matched stanza object. - instream -- Force the handler to execute during - stream processing. Used only by prerun. - Defaults to False. + :param payload: The matched + :class:`~sleekxmpp.xmlstream.stanzabase.ElementBase` object. + :param bool instream: Force the handler to execute during stream + processing. This should only be used by + :meth:`prerun()`. Defaults to ``False``. """ if not self._instream or instream: self._pointer(payload) diff --git a/sleekxmpp/xmlstream/handler/waiter.py b/sleekxmpp/xmlstream/handler/waiter.py index 25dc161c..01ff5d67 100644 --- a/sleekxmpp/xmlstream/handler/waiter.py +++ b/sleekxmpp/xmlstream/handler/waiter.py @@ -1,9 +1,12 @@ +# -*- coding: utf-8 -*- """ - SleekXMPP: The Sleek XMPP Library - Copyright (C) 2010 Nathanael C. Fritz - This file is part of SleekXMPP. + sleekxmpp.xmlstream.handler.waiter + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - See the file LICENSE for copying permission. + Part of SleekXMPP: The Sleek XMPP Library + + :copyright: (c) 2011 Nathanael C. Fritz + :license: MIT, see LICENSE for more details """ import logging @@ -22,83 +25,63 @@ log = logging.getLogger(__name__) class Waiter(BaseHandler): """ - The Waiter handler allows an event handler to block - until a particular stanza has been received. The handler - will either be given the matched stanza, or False if the - waiter has timed out. - - Methods: - check_delete -- Overrides BaseHandler.check_delete - prerun -- Overrides BaseHandler.prerun - run -- Overrides BaseHandler.run - wait -- Wait for a stanza to arrive and return it to - an event handler. + The Waiter handler allows an event handler to block until a + particular stanza has been received. The handler will either be + given the matched stanza, or ``False`` if the waiter has timed out. + + :param string name: The name of the handler. + :param matcher: A :class:`~sleekxmpp.xmlstream.matcher.base.MatcherBase` + derived object for matching stanza objects. + :param stream: The :class:`~sleekxmpp.xmlstream.xmlstream.XMLStream` + instance this handler should monitor. """ def __init__(self, name, matcher, stream=None): - """ - Create a new Waiter. - - Arguments: - name -- The name of the waiter. - matcher -- A matcher object to detect the desired stanza. - stream -- Optional XMLStream instance to monitor. - """ BaseHandler.__init__(self, name, matcher, stream=stream) self._payload = queue.Queue() def prerun(self, payload): - """ - Store the matched stanza. - - Overrides BaseHandler.prerun + """Store the matched stanza when received during processing. - Arguments: - payload -- The matched stanza object. + :param payload: The matched + :class:`~sleekxmpp.xmlstream.stanzabase.ElementBase` object. """ self._payload.put(payload) def run(self, payload): - """ - Do not process this handler during the main event loop. - - Overrides BaseHandler.run - - Arguments: - payload -- The matched stanza object. - """ + """Do not process this handler during the main event loop.""" pass def wait(self, timeout=None): - """ - Block an event handler while waiting for a stanza to arrive. + """Block an event handler while waiting for a stanza to arrive. Be aware that this will impact performance if called from a non-threaded event handler. - Will return either the received stanza, or False if the waiter - timed out. + Will return either the received stanza, or ``False`` if the + waiter timed out. - Arguments: - timeout -- The number of seconds to wait for the stanza to - arrive. Defaults to the global default timeout - value sleekxmpp.xmlstream.RESPONSE_TIMEOUT. + :param int timeout: The number of seconds to wait for the stanza + to arrive. Defaults to the the stream's + :class:`~sleekxmpp.xmlstream.xmlstream.XMLStream.response_timeout` + value. """ if timeout is None: timeout = self.stream().response_timeout - try: - stanza = self._payload.get(True, timeout) - except queue.Empty: - stanza = False - log.warning("Timed out waiting for %s" % self.name) + elapsed_time = 0 + stanza = False + while elapsed_time < timeout and not self.stream().stop.is_set(): + try: + stanza = self._payload.get(True, 1) + break + except queue.Empty: + elapsed_time += 1 + if elapsed_time >= timeout: + log.warning("Timed out waiting for %s", self.name) self.stream().remove_handler(self.name) return stanza def check_delete(self): - """ - Always remove waiters after use. - - Overrides BaseHandler.check_delete - """ + """Always remove waiters after use.""" return True |