Merge branch 'stream-features-sync-event' into 'master'
Allow "sync" events to be processed in-order See merge request poezio/slixmpp!129
This commit is contained in:
commit
5f9ab45a5e
2 changed files with 42 additions and 4 deletions
|
@ -203,14 +203,14 @@ class XEP_0077(BasePlugin):
|
|||
self.xmpp.del_filter('in', self._force_stream_feature)
|
||||
return stanza
|
||||
|
||||
def _handle_register_feature(self, features):
|
||||
async def _handle_register_feature(self, features):
|
||||
if 'mechanisms' in self.xmpp.features:
|
||||
# We have already logged in with an account
|
||||
return False
|
||||
|
||||
if self.create_account and self.xmpp.event_handled('register'):
|
||||
form = self.get_registration()
|
||||
self.xmpp.event('register', form)
|
||||
form = await self.get_registration()
|
||||
await self.xmpp.event_async('register', form)
|
||||
return True
|
||||
return False
|
||||
|
||||
|
|
|
@ -850,8 +850,46 @@ class XMLStream(asyncio.BaseProtocol):
|
|||
"""
|
||||
return len(self.__event_handlers.get(name, []))
|
||||
|
||||
def event(self, name, data={}):
|
||||
async def event_async(self, name: str, data: Any = {}):
|
||||
"""Manually trigger a custom event, but await coroutines immediately.
|
||||
|
||||
This event generator should only be called in situations when
|
||||
in-order processing of events is important, such as features
|
||||
handling.
|
||||
|
||||
:param name: The name of the event to trigger.
|
||||
:param data: Data that will be passed to each event handler.
|
||||
Defaults to an empty dictionary, but is usually
|
||||
a stanza object.
|
||||
"""
|
||||
handlers = self.__event_handlers.get(name, [])[:]
|
||||
for handler in handlers:
|
||||
handler_callback, disposable = handler
|
||||
if disposable:
|
||||
# If the handler is disposable, we will go ahead and
|
||||
# remove it now instead of waiting for it to be
|
||||
# processed in the queue.
|
||||
try:
|
||||
self.__event_handlers[name].remove(handler)
|
||||
except ValueError:
|
||||
pass
|
||||
# If the callback is a coroutine, schedule it instead of
|
||||
# running it directly
|
||||
if iscoroutinefunction(handler_callback):
|
||||
try:
|
||||
await handler_callback(data)
|
||||
except Exception as exc:
|
||||
self.exception(exc)
|
||||
else:
|
||||
try:
|
||||
handler_callback(data)
|
||||
except Exception as e:
|
||||
self.exception(e)
|
||||
|
||||
def event(self, name: str, data: Any = {}):
|
||||
"""Manually trigger a custom event.
|
||||
Coroutine handlers are wrapped into a future and sent into the
|
||||
event loop for their execution, and not awaited.
|
||||
|
||||
:param name: The name of the event to trigger.
|
||||
:param data: Data that will be passed to each event handler.
|
||||
|
|
Loading…
Reference in a new issue