From 5f2fc67c40f0cd73bee7b2cf3bc3a73d83832a50 Mon Sep 17 00:00:00 2001 From: Lance Stout Date: Tue, 7 Dec 2010 17:19:39 -0500 Subject: Added option for iq.send to accept a callhandler. The callback will be a stream level handler, and will not execute in its own thread. If you must have a thread, have the callback function raise a custom event, which can be processed by another event handler, which may run in an individual thread, like so: def handle_reply(self, iq): self.event('custom_event', iq) def do_long_operation_in_thread(self, iq): ... self.add_event_handler('custom_event', self.do_long_operation_in_thread) ...take out already prepared iq stanza... iq.send(callback=self.handle_reply) --- sleekxmpp/stanza/iq.py | 35 +++++++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 10 deletions(-) (limited to 'sleekxmpp/stanza') diff --git a/sleekxmpp/stanza/iq.py b/sleekxmpp/stanza/iq.py index 150baa00..c9877563 100644 --- a/sleekxmpp/stanza/iq.py +++ b/sleekxmpp/stanza/iq.py @@ -9,7 +9,7 @@ from sleekxmpp.stanza import Error from sleekxmpp.stanza.rootstanza import RootStanza from sleekxmpp.xmlstream import StanzaBase, ET -from sleekxmpp.xmlstream.handler import Waiter +from sleekxmpp.xmlstream.handler import Waiter, Callback from sleekxmpp.xmlstream.matcher import MatcherId @@ -157,28 +157,43 @@ class Iq(RootStanza): StanzaBase.reply(self) return self - def send(self, block=True, timeout=None): + def send(self, block=True, timeout=None, callback=None): """ Send an stanza over the XML stream. The send call can optionally block until a response is received or a timeout occurs. Be aware that using blocking in non-threaded event - handlers can drastically impact performance. + handlers can drastically impact performance. Otherwise, a callback + handler can be provided that will be executed when the Iq stanza's + result reply is received. Be aware though that that the callback + handler will not be executed in its own thread. + + Using both block and callback is not recommended, and only the + callback argument will be used in that case. Overrides StanzaBase.send Arguments: - block -- Specify if the send call will block until a response - is received, or a timeout occurs. Defaults to True. - timeout -- The length of time (in seconds) to wait for a response - before exiting the send call if blocking is used. - Defaults to sleekxmpp.xmlstream.RESPONSE_TIMEOUT + block -- Specify if the send call will block until a response + is received, or a timeout occurs. Defaults to True. + timeout -- The length of time (in seconds) to wait for a response + before exiting the send call if blocking is used. + Defaults to sleekxmpp.xmlstream.RESPONSE_TIMEOUT + callback -- Optional reference to a stream handler function. Will + be executed when a reply stanza is received. """ if timeout is None: timeout = self.stream.response_timeout - if block and self['type'] in ('get', 'set'): + if callback is not None and self['type'] in ('get', 'set'): + handler = Callback('IqCallback_%s' % self['id'], + MatcherId(self['id']), + callback, + once=True) + self.stream.register_handler(handler) + return None + elif block and self['type'] in ('get', 'set'): waitfor = Waiter('IqWait_%s' % self['id'], MatcherId(self['id'])) - self.stream.registerHandler(waitfor) + self.stream.register_handler(waitfor) StanzaBase.send(self) return waitfor.wait(timeout) else: -- cgit v1.2.3 From 19bd1e0485936c8695868b22e619df8b199d73b5 Mon Sep 17 00:00:00 2001 From: Lance Stout Date: Tue, 7 Dec 2010 23:04:04 -0500 Subject: Actually make the Iq callbacks work for real. --- sleekxmpp/stanza/iq.py | 1 + 1 file changed, 1 insertion(+) (limited to 'sleekxmpp/stanza') diff --git a/sleekxmpp/stanza/iq.py b/sleekxmpp/stanza/iq.py index c9877563..906e6648 100644 --- a/sleekxmpp/stanza/iq.py +++ b/sleekxmpp/stanza/iq.py @@ -190,6 +190,7 @@ class Iq(RootStanza): callback, once=True) self.stream.register_handler(handler) + StanzaBase.send(self) return None elif block and self['type'] in ('get', 'set'): waitfor = Waiter('IqWait_%s' % self['id'], MatcherId(self['id'])) -- cgit v1.2.3