diff --git a/docs/api.rst b/docs/api.rst index b1c2ef3d..c75f5d37 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -68,9 +68,8 @@ contexts. instances and returns the first value posted to any receiver or select. If `oneshot` is ``True``, then remove each receiver as it yields a result; - since :py:meth:`__iter__` terminates once the final receiver is removed - from the select, this makes it convenient to respond to several call - results with minimal effort: + since :py:meth:`__iter__` terminates once the final receiver is removed, + this makes it convenient to respond to calls made in parallel: .. code-block:: python @@ -78,26 +77,25 @@ contexts. recvs = [c.call_async(long_running_operation) for c in contexts] with mitogen.master.Select(recvs) as select: - for recv, msg in select: - value = msg.unpickle() - print 'Got %s from %s' % (value, recv) - total += value + for recv, (msg, data) in select: + print 'Got %s from %s' % (data, recv) + total += data # Iteration ends when last Receiver yields a result. print 'Received total %s from %s receivers' % (total, len(recvs)) - :py:class:`Select` may also be used to drive a long-running scheduler: + :py:class:`Select` may drive a long-running scheduler: .. code-block:: python - with mitogen.master.Select() as select: + with mitogen.master.Select(oneshot=False) as select: while running(): - for recv, msg in select: + for recv, (msg, data) in select: process_result(recv.context, msg.unpickle()) for context, workfunc in get_new_work(): select.add(context.call_async(workfunc)) - :py:class:`Select` may be arbitrarily nested: + :py:class:`Select` may be nested: .. code-block:: python @@ -110,9 +108,9 @@ contexts. ]) ] - with mitogen.master.Select(selects, oneshot=False) as select: - while subselects and any(subselects): # Calls __bool__() - print select.get() + with mitogen.master.Select(selects) as select: + for _, (msg, data) in select: + print data .. py:method:: get (timeout=None) @@ -138,17 +136,16 @@ contexts. .. py:method:: empty () - Return ``True`` if no items appear to be queued on this receiver. + Return ``True`` if calling :py:meth:`get` would block. - As with :py:class:`Queue.Queue`, this function may return ``False`` - even though a subsequent call to :py:meth:`get` will succeed, since a - message may be posted at any moment between the call to - :py:meth:`empty` and :py:meth:`get`. + As with :py:class:`Queue.Queue`, ``True`` may be returned even though a + subsequent call to :py:meth:`get` will succeed, since a message may be + posted at any moment between :py:meth:`empty` and :py:meth:`get`. - :py:meth:`empty` may additionally return ``True`` when :py:meth:`get` - would block if another thread has drained a receiver added to this - select. This can be avoided by only consuming each receiver from a - single thread. + :py:meth:`empty` may return ``False`` even when :py:meth:`get` would + block if another thread has drained a receiver added to this select. + This can be avoided by only consuming each receiver from a single + thread. .. py:method:: __iter__ (self) diff --git a/docs/index.rst b/docs/index.rst index a9329342..885a9244 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -173,8 +173,8 @@ for example enforce an interactive TTY and account password. ]) -Inter-slave Message Routing -########################### +Message Routing +############### .. image:: images/route.png @@ -255,8 +255,30 @@ and timeouts can be configured to ensure failed calls do not block progress of the parent. -Support For Single File Programs -################################ +Scatter/Gather Calls +#################### + +Functions may be invoked asynchronously, with results returned as they become +available. + +.. code-block:: python + + def usage(path): + return sum((os.path.getsize(os.path.join(dirpath, name)) + for dirpath, dirnames, filenames in os.walk(path) + for name in dirnames + filenames), 0) + + total = 0 + for recv, msg in Select(c.call_async(usage, '/tmp') for c in contexts): + value = result.unpickle() + print 'Context %s /tmp usage: %d' % (recv.context, value) + total += value + + print 'Total /tmp usage across all contexts: %d' % (total,) + + +Single File Programs +#################### Programs that are self-contained within a single Python script are supported. External contexts are configured such that any attempt to execute a function @@ -298,33 +320,6 @@ usual into the slave process. mitogen.utils.run_with_broker(main) -Scatter/Gather Function Calls -############################# - -Functions may be invoked asynchronously, with results returned as they become -available. - -.. code-block:: python - - def disk_usage(path): - return sum((os.path.getsize(os.path.join(dirpath, name)) - for dirpath, dirnames, filenames in os.walk(path) - for name in dirnames + filenames), 0) - - - if __name__ == '__main__' and mitogen.is_master: - contexts = connect_contexts(...) - receivers = [c.call_async(disk_usage, '/tmp') for c in contexts] - total = 0 - - for recv, msg in mitogen.master.Select(receivers): - value = result.unpickle() - print 'Context %s /tmp usage: %d' % (recv.context, value) - total += value - - print 'Total /tmp usage across all contexts: %d' % (total,) - - Event-driven IO ###############