Module Expr Str ImportFrom alias alias ImportFrom alias ClassDef bases NameLoad body FunctionDef arguments args NameParam NameParam defaults body Assign AttributeStore NameLoad attr NameLoad Assign AttributeStore NameLoad attr Call AttributeLoad NameLoad attr TryExcept body Expr Call AttributeLoad NameLoad attr Call AttributeLoad AttributeLoad NameLoad attr attr handlers ExceptHandler type NameLoad body Pass decorator_list FunctionDef arguments args NameParam NameParam NameParam defaults body Expr Call AttributeLoad AttributeLoad NameLoad attr attr Call NameLoad AttributeLoad NameLoad attr NameLoad NameLoad decorator_list FunctionDef arguments args NameParam NameParam NameParam defaults body TryExcept body Assign NameStore IfExp NameLoad SubscriptLoad NameLoad Index Num NameLoad If Call NameLoad NameLoad NameLoad body Expr Call AttributeLoad NameLoad attr Call AttributeLoad AttributeLoad NameLoad attr attr NameLoad orelse Expr Call AttributeLoad NameLoad attr Call AttributeLoad AttributeLoad NameLoad attr attr NameLoad handlers ExceptHandler type NameLoad body Pass decorator_list FunctionDef arguments args NameParam NameParam defaults body Assign NameStore UnaryOpNot Call NameLoad NameLoad Str If NameLoad body Assign NameStore ListLoad NameLoad Assign AttributeStore NameLoad attr Call NameLoad Call NameLoad NameLoad Assign NameStore BinOpMult ListLoad NameLoad AttributeLoad NameLoad attr If CompareEq AttributeLoad NameLoad attr Num body Expr Call AttributeLoad NameLoad attr NameLoad NameLoad orelse For TupleStore NameStore NameStore Call NameLoad NameLoad body Expr Call NameLoad keyword Call NameLoad AttributeLoad NameLoad attr NameLoad NameLoad NameLoad decorator_list FunctionDef arguments args NameParam NameParam NameParam NameParam NameParam defaults body AugAssignSub AttributeStore NameLoad attr Num Assign SubscriptStore NameLoad Index NameLoad NameLoad If CompareGt AttributeLoad NameLoad attr Num body Return Expr Call AttributeLoad NameLoad attr NameLoad NameLoad decorator_list decorator_list FunctionDef arguments args NameParam defaults body FunctionDef arguments args defaults vararg kwarg body Expr Call NameLoad Call NameLoad NameLoad NameLoad decorator_list Call NameLoad NameLoad Return NameLoad decorator_list FunctionDef arguments args NameParam NameParam NameParam defaults Str Lambda arguments args NameParam defaults NameLoad body FunctionDef arguments args defaults vararg kwarg body FunctionDef arguments args NameParam defaults body Assign SubscriptStore NameLoad Index NameLoad Call NameLoad NameLoad Return Call NameLoad NameLoad NameLoad decorator_list Return NameLoad decorator_list Call NameLoad NameLoad Return NameLoad decorator_list
N/A N/A 
Adisp is a library that allows structuring code with asynchronous calls and
callbacks without defining callbacks as separate functions. The code then
becomes sequential and easy to read. The library is not a framework by itself
and can be used in other environments that provides asynchronous working model
(see an example with Tornado server in proxy_example.py).

Organizing calling code
-----------------------

All the magic is done with Python 2.5 decorators that allow for control flow to
leave a function, do sometihing else for some time and then return into the
calling function with a result. So the function that makes asynchronous calls
should look like this::

   @process
   def my_handler():
      response = yield some_async_func()
      data = parse_response(response)
      result = yield some_other_async_func(data)
      store_result(result)

Each `yield` is where the function returns and lets the framework around it to
do its job. And the code after `yield` is what usually goes in a callback.

The ``@process`` decorator is needed around such a function. It makes it callable
as an ordinary function and takes care of dispatching callback calls back into
it.

Writing asynchronous function
-----------------------------

In the example above functions ``some_async_func`` and
``some_other_async_func`` are those that actually run an asynchronous process.
They should follow two conditions:

- accept a ``callback`` parameter with a callback function that they should call
  after an asynchronous process is finished
- a callback should be called with one parameter -- the result
- be wrapped in the ``@async`` decorator

The ``@async`` decorator makes a function call lazy allowing the ``@process`` that
calls it to provide a callback to call.

Using async with ``@-syntax`` is most convenient when you write your own
asynchronous function (and can make your callback parameter to be named
"callback"). But when you want to call some library function you can wrap it in
async in place.

::

   # call http.fetch(url, callback=callback)
   result = yield async(http.fetch)

   # call http.fetch(url, cb=safewrap(callback))
   result = yield async(http.fetch, cbname='cb', cbwrapper=safewrap)(url)

Here you can use two optional parameters for async:

- `cbname`: a name of a parameter in which the function expects callbacks
- `cbwrapper`: a wrapper for the callback iself that will be applied before
  calling it

Chain calls
-----------

``@async`` function can also be ``@process``'es allowing to effectively chain
asynchronous calls as it can be done with normal functions. In this case the
``@async`` decorator shuold be the outer one::

   @async
   @process
   def async_calling_other_asyncs(arg, callback):
       # ....

Multiple asynchronous calls
---------------------------

The library also allows to call multiple asynchronous functions in parallel and
get all their result for processing at once::

   @async
   def async_http_get(url, callback):
       # get url asynchronously
       # call callback(response) at the end

   @process
   def get_stat():
       urls = ['http://.../', 'http://.../', ... ]
       responses = yield map(async_http_get, urls)

After *all* the asynchronous calls will complete ``responses`` will be a list of
responses corresponding to given urls.
 functools partial wraps tornado.ioloop IOLoop CallbackDispatcher N/A object N/A __init__ N/A N/A self generator N/A N/A N/A N/A self g generator N/A N/A self io_loop N/A N/A IOLoop instance N/A N/A N/A N/A N/A self call N/A N/A N/A self g next N/A N/A N/A StopIteration N/A N/A N/A _queue_send_result N/A N/A self result single N/A N/A N/A N/A N/A N/A self io_loop add_callback N/A partial N/A self _send_result result single N/A _send_result N/A N/A self results single N/A N/A N/A N/A N/A result N/A single N/A results N/A 0 results N/A N/A isinstance result Exception N/A N/A N/A N/A self call N/A N/A N/A self g throw result N/A N/A N/A N/A self call N/A N/A N/A self g send result N/A N/A N/A StopIteration N/A N/A N/A call N/A N/A self callers N/A N/A N/A single N/A N/A hasattr callers __iter__ N/A single N/A N/A callers N/A callers N/A N/A self call_count N/A len N/A list callers N/A results N/A N/A None N/A self call_count N/A N/A N/A self call_count 0 N/A N/A N/A N/A self _queue_send_result results single N/A N/A N/A count caller N/A enumerate callers N/A N/A N/A caller callback N/A partial N/A self callback results count single N/A callback N/A N/A self results index single arg N/A N/A N/A N/A self call_count 1 N/A N/A results N/A index arg N/A N/A N/A self call_count 0 N/A N/A N/A N/A N/A self _queue_send_result results single N/A N/A process N/A N/A func N/A N/A wrapper N/A N/A N/A args kwargs N/A N/A N/A CallbackDispatcher N/A func args kwargs N/A N/A wraps func N/A wrapper N/A async N/A N/A func cbname cbwrapper N/A callback N/A N/A N/A x N/A x N/A wrapper N/A N/A N/A args kwargs N/A caller N/A N/A callback N/A N/A N/A N/A kwargs N/A cbname N/A cbwrapper callback N/A N/A func args kwargs N/A N/A caller N/A N/A wraps func N/A wrapper N/A