pyaib's eponymous asynchronous nature makes it difficult - if not outright impossible - to pass data between greenlets, or pause a greenlet to wait for some event.
Not good enough for me - I had a situation where I needed a keyword command to request a fresh NAMES response from the server and compare that to the cached NAMES response in my database. How could I possibly do that? In a function decorated with @keyword, I can't stop it in the middle and wait for @observe('IRC_MSG_353'). They would both have to be handled by different functions - different, completely separate, asynchronous functions.
This PR introduces a new concept: Signals, which are pretty much a fork of Events. Signals are messages broadcasted from one greenlet to all others. They have a name/ID and can carry data with them.
This PR introduces a new decorator and two new functions:
pyaib.signals.emit_signal: a non-blocking function that emits a signal. Takes arguments irc_context and the name/ID of the signal to be broadcasted. Has an optional data kwarg that specifies an object to be sent along with the signal, which all recipient greenlets will recieve.
pyaib.components.awaits_signal: a decorator for plugin functions. The function is called when the signal is received. (Added for consistency with Events; not sure I see a use case)
pyaib.signals.await_signal: a function that blocks until the signal is recieved. Takes arguments irc_context and the name/ID of the signal to wait for. Has an optional timeout kwarg which is a float specifying the number of seconds to wait for before raising TimeoutError. If not specified, it will wait forever. Returns whatever data was transmitted along with the signal, defaulting to None.
pyaib's eponymous asynchronous nature makes it difficult - if not outright impossible - to pass data between greenlets, or pause a greenlet to wait for some event.
Not good enough for me - I had a situation where I needed a keyword command to request a fresh NAMES response from the server and compare that to the cached NAMES response in my database. How could I possibly do that? In a function decorated with
@keyword
, I can't stop it in the middle and wait for@observe('IRC_MSG_353')
. They would both have to be handled by different functions - different, completely separate, asynchronous functions.This PR introduces a new concept: Signals, which are pretty much a fork of Events. Signals are messages broadcasted from one greenlet to all others. They have a name/ID and can carry data with them.
This PR introduces a new decorator and two new functions:
pyaib.signals.emit_signal
: a non-blocking function that emits a signal. Takes argumentsirc_context
and the name/ID of the signal to be broadcasted. Has an optionaldata
kwarg that specifies an object to be sent along with the signal, which all recipient greenlets will recieve.pyaib.components.awaits_signal
: a decorator for plugin functions. The function is called when the signal is received. (Added for consistency with Events; not sure I see a use case)pyaib.signals.await_signal
: a function that blocks until the signal is recieved. Takes argumentsirc_context
and the name/ID of the signal to wait for. Has an optionaltimeout
kwarg which is a float specifying the number of seconds to wait for before raisingTimeoutError
. If not specified, it will wait forever. Returns whateverdata
was transmitted along with the signal, defaulting to None.Example usage (a truncated examples/plugins/signals.py):
The development process can be found here: https://github.com/rossjrw/pyaib/pull/1