diff --git a/doc/basic_usage.rst b/doc/basic_usage.rst index 4706dda..9674d46 100644 --- a/doc/basic_usage.rst +++ b/doc/basic_usage.rst @@ -73,33 +73,38 @@ Primary API The design goal for Eventlet's API is simplicity and readability. You should be able to read its code and understand what it's doing. Fewer lines of code are preferred over excessively clever implementations. `Like Python itself `_, there should be one, and only one obvious way to do it in Eventlet! -Though Eventlet has many modules, much of the most-used stuff is accessible simply by doing ``import eventlet`` +Though Eventlet has many modules, much of the most-used stuff is accessible simply by doing ``import eventlet``. Here's a quick summary of the functionality available in the ``eventlet`` module, with links to more verbose documentation on each. .. function:: eventlet.spawn(func, *args, **kw) - This launches a greenthread to call *func*. Spawning off multiple greenthreads gets work done in parallel. The return value from ``spawn`` is a :class:`greenthread.GreenThread` object, which can be used to retrieve the return value of *func*. See :func:`greenthread.spawn` for more details. + This launches a greenthread to call *func*. Spawning off multiple greenthreads gets work done in parallel. The return value from ``spawn`` is a :class:`greenthread.GreenThread` object, which can be used to retrieve the return value of *func*. See :func:`spawn ` for more details. .. function:: eventlet.spawn_n(func, *args, **kw) - The same as :func:`spawn`, but it's not possible to retrieve the return value. This makes execution faster. See :func:`greenthread.spawn_n` for more details. + The same as :func:`spawn`, but it's not possible to retrieve the return value. This makes execution faster. See :func:`spawn_n ` for more details. -.. function:: eventlet.sleep(seconds) +.. function:: eventlet.spawn_after(seconds, func, *args, **kw) + + Spawns *func* after *seconds* have elapsed; a delayed version of :func:`spawn`. To abort the spawn and prevent *func* from being called, call :meth:`GreenThread.cancel` on the return value of :func:`spawn_after`. See :func:`spawn_after ` for more details. - Suspends the current greenthread and allows others a chance to process. See :func:`greenthread.sleep` for more details. +.. function:: eventlet.sleep(seconds=0) + + Suspends the current greenthread and allows others a chance to process. See :func:`sleep ` for more details. .. class:: eventlet.GreenPool - Pools control concurrency. It's very common in applications to want to consume only a finite amount of memory, or to restrict the amount of connections that one part of the code holds open so as to leave more for the rest, or to behave consistently in the face of unpredictable input data. GreenPools provide this control. See :class:`greenpool.GreenPool` for more on how to use these. + Pools control concurrency. It's very common in applications to want to consume only a finite amount of memory, or to restrict the amount of connections that one part of the code holds open so as to leave more for the rest, or to behave consistently in the face of unpredictable input data. GreenPools provide this control. See :class:`GreenPool ` for more on how to use these. .. class:: eventlet.GreenPile - Sister class to the GreenPool, GreenPile objects represent chunks of work. In essence a GreenPile is an iterator that can be stuffed with work, and the results read out later. See :class:`greenpool.GreenPile` for more details. + GreenPile objects represent chunks of work. In essence a GreenPile is an iterator that can be stuffed with work, and the results read out later. See :class:`GreenPile ` for more details. .. class:: eventlet.Queue - Queues are a fundamental construct for communicating data between execution units. Eventlet's Queue class is used to communicate between greenthreads, and provides a bunch of useful features for doing that. See :class:`queue.Queue` for more details. + Queues are a fundamental construct for communicating data between execution units. Eventlet's Queue class is used to communicate between greenthreads, and provides a bunch of useful features for doing that. See :class:`Queue ` for more details. .. class:: eventlet.Timeout + Raises *exception* in the current greenthread after *timeout* seconds:: timeout = Timeout(seconds, exception) diff --git a/doc/index.rst b/doc/index.rst index c0c86c0..2cc5103 100644 --- a/doc/index.rst +++ b/doc/index.rst @@ -38,11 +38,11 @@ Contents threading hubs testing - history modules authors + history License --------- diff --git a/doc/modules.rst b/doc/modules.rst index ca69e3d..1007ead 100644 --- a/doc/modules.rst +++ b/doc/modules.rst @@ -12,9 +12,6 @@ Module Reference modules/greenpool modules/greenthread modules/pools - modules/processes modules/queue - modules/saranwrap modules/semaphore - modules/util modules/wsgi diff --git a/doc/modules/backdoor.rst b/doc/modules/backdoor.rst index 6dd4dcb..79b2fdf 100644 --- a/doc/modules/backdoor.rst +++ b/doc/modules/backdoor.rst @@ -1,6 +1,27 @@ :mod:`backdoor` -- Python interactive interpreter within a running process =============================================================================== +The backdoor module is convenient for inspecting the state of a long-running process. It supplies the normal Python interactive interpreter in a way that does not block the normal operation of the application. This can be useful for debugging, performance tuning, or simply learning about how things behave in situ. + +In the application, spawn a greenthread running backdoor_server on a listening socket:: + + eventlet.spawn(backdoor.backdoor_server, eventlet.listen(('localhost', 3000))) + +When this is running, the backdoor is accessible via telnet to the specified port. + +.. code-block:: sh + + $ telnet localhost 3000 + Python 2.6.2 (r262:71600, Apr 16 2009, 09:17:39) + [GCC 4.0.1 (Apple Computer, Inc. build 5250)] on darwin + Type "help", "copyright", "credits" or "license" for more information. + >>> import myapp + >>> dir(myapp) + ['__all__', '__doc__', '__name__', 'myfunc'] + >>> + +The backdoor cooperatively yields to the rest of the application between commands, so on a running server continuously serving requests, you can observe the internal state changing between interpreter commands. + .. automodule:: eventlet.backdoor :members: diff --git a/doc/modules/greenpool.rst b/doc/modules/greenpool.rst index 9f79d88..0bf031f 100644 --- a/doc/modules/greenpool.rst +++ b/doc/modules/greenpool.rst @@ -3,3 +3,4 @@ .. automodule:: eventlet.greenpool :members: + diff --git a/doc/patching.rst b/doc/patching.rst index 491278a..d837367 100644 --- a/doc/patching.rst +++ b/doc/patching.rst @@ -42,7 +42,8 @@ Monkeypatching the Standard Library The other way of greening an application is simply to monkeypatch the standard library. This has the disadvantage of appearing quite magical, but the advantage of avoiding the late-binding problem. -.. function:: eventlet.patcher.monkey_patch(all=True, os=False, select=False, socket=False, thread=False, time=False): +.. function:: eventlet.patcher.monkey_patch(all=True, os=False, select=False, socket=False, thread=False, time=False) + By default, this function monkeypatches the key system modules by replacing their key elements with green equivalents. The keyword arguments afford some control over which modules are patched, in case that's important. If *all* is True, then all modules are patched regardless of the other arguments. If it's False, then the rest of the keyword arguments control patching of specific subsections of the standard library. Most patch the single module of the same name (e.g. time=True means that the time module is patched [time.sleep is patched by eventlet.sleep]). The exceptions to this rule are *socket*, which also patches the :mod:`ssl` module if present; and *thread*, which patches :mod:`thread`, :mod:`threading`, and :mod:`Queue`. Here's an example of using monkey_patch to patch only a few modules:: diff --git a/eventlet/backdoor.py b/eventlet/backdoor.py index 82d308e..e3bc95b 100644 --- a/eventlet/backdoor.py +++ b/eventlet/backdoor.py @@ -72,6 +72,10 @@ def backdoor_server(sock, locals=None): """ Blocking function that runs a backdoor server on the socket *sock*, accepting connections and running backdoor consoles for each client that connects. + + The *locals* argument is a dictionary that will be included in the locals() + of the interpreters. It can be convenient to stick important application + variables in here. """ print "backdoor server listening on %s:%s" % sock.getsockname() try: diff --git a/eventlet/event.py b/eventlet/event.py index 4a5d3e7..2a08c5a 100644 --- a/eventlet/event.py +++ b/eventlet/event.py @@ -17,10 +17,10 @@ class Event(object): in two important ways: 1. calling :meth:`send` never unschedules the current greenthread - 2. :meth:`send` can only be called once; use :meth:`reset` to prepare the - event for another :meth:`send` - - They are good for communicating results between coroutines. + 2. :meth:`send` can only be called once; create a new event to send again. + + They are good for communicating results between coroutines, and are the + basis for how :meth:`GreenThread.wait() ` is implemented. >>> from eventlet import event >>> import eventlet diff --git a/eventlet/greenthread.py b/eventlet/greenthread.py index 221fe30..6027002 100644 --- a/eventlet/greenthread.py +++ b/eventlet/greenthread.py @@ -38,7 +38,7 @@ def spawn(func, *args, **kwargs): Execution control returns immediately to the caller; the created greenthread is merely scheduled to be run at the next available opportunity. - Use :func:`call_after_global` to arrange for greenthreads to be spawned + Use :func:`spawn_after` to arrange for greenthreads to be spawned after a finite delay. """ hub = hubs.get_hub() @@ -55,9 +55,8 @@ def _main_wrapper(func, args, kwargs): def spawn_n(func, *args, **kwargs): """Same as :func:`spawn`, but returns a ``greenlet`` object from which it is - not possible to retrieve the results. This is slightly faster - than :func:`spawn` in all cases; it is fastest if there are no keyword - arguments.""" + not possible to retrieve the results. This is faster than :func:`spawn`; + it is fastest if there are no keyword arguments.""" return _spawn_n(0, func, args, kwargs)[1] @@ -195,8 +194,8 @@ def _spawn_n(seconds, func, args, kwargs): class GreenThread(greenlet.greenlet): """The GreenThread class is a type of Greenlet which has the additional - property of having a retrievable result. Do not construct GreenThread - objects directly; call :func:`spawn` to get one. + property of being able to retrieve the return value of the main function. + Do not construct GreenThread objects directly; call :func:`spawn` to get one. """ def __init__(self, parent): greenlet.greenlet.__init__(self, self.main, parent)