Documentation for pulsar 0.9.2. For development docs, go here.
Greenlet support facilitates the integration of synchronous third-party libraries into pulsar asynchronous framework. It requires the greenlet library.
If you want to understand how integration works but you are unfamiliar with greenlets, check out the greenlet documentation first. On the other hand, if you need to use it in the context of asynchronous psycopg2 connections for example, you can skip the implementation details.
This application does not use monkey patching and therefore it works quite differently from implicit asynchronous libraries such as gevent. All it does, it provides the user with a limited set of utilities for explicitly transferring execution from one greenlet to a another which execute the blocking call in a greenlet-friendly way.
The caller has the responsibility that the blocking call is greenlet-friendly, i.e. it transfers the control of execution back to the parent greenlet when needed.
Lets assume you are building an application which uses pulsar asynchronous engine and would like to
Future
or
coroutines, in other words in an implicit asynchronous style. In this way
your client code can be used on other frameworks just as well.In both cases, the greenio
application is what you need.
Assume you are using pulsar web server and would like to write your application
in an implicit asynchronous mode, i.e. without dealing with futures nor
coroutines, then you can wrap your wsgi app
with the RunInPool
utility:
from pulsar.apps import wsgi, greenio
callable = wsgi.WsgiHandler([wsgi.wait_for_body_middleware,
greenio.RunInPool(app, 20)])
wsgi.WsgiServer(callable=callable).start()
The RunInPool
manages a pool of greenlets which execute your
application. In this way, within your app
you can invoke the
wait()
function when needing to wait for asynchronous results to be
ready.
The HttpClient
can be used with greenlets:
>>> from pulsar.apps.http import HttpClient
>>> http = HttpClient(green=True)
>>> http.green
True
And now you can write synchronous looking code and run it in a separate
greenlet via the run_in_greenlet()
decorator:
@greenio.run_in_greenlet
def example():
response = http.get('http://bbc.co.uk')
...
return 'done'
and somewhere, in your asynchronous code:
result = yield example()
result == 'done'
the run_in_greenlet()
decorator, execute the function on a child
greenlet without blocking the asynchronous engine. Once the example
function returns, the asynchronous code continue from the yield
statement as usual.
pulsar.apps.greenio.
wait
(coro_or_future, loop=None)[source]¶Wait for a coroutine or a Future
to complete.
This function must be called from a greenlet other than the main one.
It can be used in conjunction with the run_in_greenlet()
decorator or the GreenPool
.
pulsar.apps.greenio.
wait_fd
(fd, read=True)[source]¶Wait for an event on file descriptor fd
.
Parameters: |
|
---|
This function must be invoked from a coroutine with parent, therefore
invoking it from the main greenlet will raise an exception.
Check how this function is used in the psycopg2_wait_callback()
function.
pulsar.apps.greenio.
green_task
(method)[source]¶Decorator to run a method
an a new greenlet in the event loop
of the instance of the bound method
.
This method is the greenlet equivalent of the task()
decorator.
The instance must be an async object.
Returns: | a Future |
---|
pulsar.apps.greenio.pool.
RunInPool
(app, max_workers=None, loop=None)[source]¶Utility for running a callable in a GreenPool
.
Parameters: |
|
---|
THis utility is used by the pulse
application.
Pulsar greenio
application can be used in conjunction
with psycopg2 coroutine support to
query the PostgreSql database in an implicit
asynchronous fashion.
Such feature can be extremely useful since it allows to write
asynchronous code without the need to explicitly yield
control appropriately when necessary.
For example, one could use ORMs (Object Relational Mappers) such as
SqlAlchemy and django in asynchronous mode
by invoking make_asynchronous()
somehere convinient in the code:
from pulsar.apps.greenio import pg
pg.make_asynchronous()
The make_asynchronous()
set the psycopg2_wait_callback()
function
as the waiting callback in psycopg2.
See also
Check out how the pulse
application uses greenlet
support to asynchrnously execute django middleware when using
PostgreSql as backend database.