Documentation for pulsar 0.9.2. For development docs, go here.
We assume you are familiar with python Web Standard Gateway Interface (WSGI), if not you should read pep-3333 first.
All pulsar needs to set-up a WSGI server is the callable of your
application. We start by creating a script, called managed.py
which will be used to run your server:
from pulsar.apps import wsgi
def callable(environ, start_response):
...
if __name__ == '__main__':
wsgi.WSGIServer(callable).start()
When serving lots of requests, an asynchronous single-process server may not be enough. To add power, you can run the server using 2 or more process (workers):
python manage.py --workers 4
Multi-process servers are only available for:
Check multi-process socket servers documentation for more information.
Pulsar is an asynchronous server, however, the callable which consume your application may not be.
Note
Most web-framework in the public domain are blocking by construction. This is OK as long as the WSGI callable consumes the request and return control to pulsar as fast as possible.
In order to facilitate the integration of blocking frameworks, pulsar ships with several WSGI utilities, including:
WsgiHandler
for grouping several WSGI middleware togetherwait_for_body_middleware()
should be placed before any synchronous middleware
which needs to process the body of the HTTP request (such as POST methods)middleware_in_executor()
, a wrapper to execute a blocking middleware in the
executor (threading pool) of the actor serving the request.A pulsar friendly WSGI handler for a callable
can take the following form:
from pulsar.apps import wsgi
def callable(environ, start_response):
...
wsgi_handler = wsgi.WsgiHandler([wsgi.wait_for_body_middleware,
wsgi.middleware_in_executor(callable)])
if __name__ == '__main__':
wsgi.WSGIServer(wsgi_handler()).start()
To control the number of thread workers in the event loop executor, one uses the thread-workers option. For example, the following command:
python manage.py -w 4 --thread-workers 10
will run four process based actors, each with an executor with up to 10 threads.
You can serve as many applications, on different addresses, as you like.
For example, our manage.py
script could be:
from pulsar import arbiter
from pulsar.apps import wsgi
def callable1(environ, start_response):
...
def callable2(environ, start_response):
...
if __name__ == '__main__':
wsgi.WSGIServer(callable1, name='wsgi1')
wsgi.WSGIServer(callable2, name='wsgi2', bind=8070)
arbiter().start()