Signals library for Google App Engine.
What is this?
Signals are used in complex applications to decouple event dispatch from event handling. A typical use case is having one module send a signal (corresponding to some application-specific event) and have some other module receive it at some later time, and handle appropriately.
In web applications signals are especially useful. They allow foreground requests to generate events which defer expensive computation for later time. Background processes can then have such signals delivered and perform those time-consuming tasks without increasing visible latency.
Sending a signal is as easy as invoking the
from gaesignals import send send('my_signal') # optional data to be passed along from datetime import datetime send('my_signal', datetime.now())
Delivery can be performed at any time using the
deliver function. It takes a mapping,
associating signal names to their handlers - similarly to webapp's
routing of request handlers:
from gaesignals import deliver import logging def my_signal_handler(signal, data): logging.info("Received %s with data: %r", signal, data) deliver([ ('my_signal', my_signal_handler), ])
Alternatively, you can use the WSGI middleware, which delivers specified signals at the start of request:
# appengine_config.py from gaesignals import SignalsMiddleware from myapp.signals import my_signal_handler def webapp_add_wsgi_middleware(app): app = SignalsMiddleware(app, [ ('my_signal', my_signal_handler) ]) return app
In practice, you would want to deliver different signals at different times. For example, signals that
are specific to current user should be dispatched when the user is already authenticated - e.g. in
post method of
RequestHandler if using the webapp framework.
By default, gae-signals minimalizes the overhead of signal delivery by using only two memcache operations
for single call to
deliver. That's why it is beneficial to aggregate as many signals as possible
in single mapping.
Choosing delivery mode
However, this efficient delivery method may rarely result in some signals being lost or delivered more than once.
This can happen especially in times of very intensive usage. If this poses a problem to your application, you can
choose to deliver some signals reliably - at the expense of speed - by passing the
deliver([ ('important_signal', important_signal_handler) ], reliable=True)
This increased the overhead to two memcache calls per signal, along with at least two more calls due to using a memcache-based synchronization lock. Therefore using the default ("weak") delivery mode is recommended.
For best results, you should use finely-grained signals whose scope is as small as possible. For example,
having a global signal
'user_signed_up' may prove troublesome if it's triggered many times per second.
On the other hand, something like
user_54274_password_change - that is, signal specific to
a single user - should be absolutely fine in all reasonable cases.
gae-signals is licensed under MIT license.