Usage¶
To use py-emit in a project
step 1. Import pyemit¶
from pyemit import emit
step 2. Register events¶
pyemit provides both annotation based registering and direct registering. Annotation can be used if the handler is not a class method.
Be noticed that the handler MUST be a coroutine function.
from pyemit import emit
@emit.on('event_name')
async def handler(msg):
pass
or, if it’s a class method, use emit.register
instead:
from pyemit import emit
class Foo:
async def bar(self, msg):
pass
foo = Foo()
emit.register('event_name', foo.bar)
To know what causes the difference, please refer to $todo
step 3. Start the message pumping¶
you can start a local message pump by:
from pyemit import emit
async def init():
await emit.start()
Or, if you’re prefer a remote message server, use this:
from pyemit import emit
# aioredis is required. You can install it by running `pip install aioredis>=1.3.1
async def init(dsn):
await emit.start(emit.Engine.REDIS, dsn=dsn)
step 4. Fire and consume events¶
Now you can fire and consume events. To emit a message, running:
from pyemit import emit
async def foo():
# construct msg
msg = {}
await emit.emit('event_name', msg)
You can fire an event without providing any message. By doing so, be sure provide no parameter to the handler. The msg must be and dict and is json serializable.
Troubeshooting¶
You can enable heartbeat when using REDIS engine:
from pyemit import emit
async def init(dsn):
await emit.start(emit.Engine.REDIS, dsn=dsn, heart_beat=1)
and set logging level to DEBUG, this should print a heart beat msg every 1 second. If not seen, then check your configurations and Redis setup.
Advanced topic¶
RPC call¶
from pyemit import emit as e
from pyemit.remote import Remote
class Sum(Remote):
def __init__(self, to_be_sum):
super().__init__()
self.to_be_sum = to_be_sum
async def server_impl(self, *args, **kwargs):
result = sum(self.to_be_sum)
await super().respond(result)
async def test_rpc():
await e.start(e.Engine.REDIS, dsn="redis://localhost")
foo = Sum([0, 1, 2])
response = await foo.invoke()
assert response == 3
step 1. Subclass from Remote
, and implement Remote.server_impl
method. This one is supposed to be executed on
the server side. When calculation is done, then call super().respond()
to send the result back to client
step 2. At client side, create instance of the subclass you defined (i.e., foo
in the example), then by calling
await foo.invoke()
you will get what you want.
pass parameters during construct of Remote object if any, they can be access at server side by self object.
stop the message pump¶
call emit.stop
to stop the whole machine. call emit.unsubscribe
to remove a handler.