From c1e111fd11c1b13317c0dc2cd5af5af32a7bc609 Mon Sep 17 00:00:00 2001 From: Guido van Rossum Date: Fri, 21 Dec 2012 22:10:48 -0800 Subject: [PATCH] Replace par() with wait() and as_completed(), --- pep-3156.txt | 45 ++++++++++++++++++++++++++++++--------------- 1 file changed, 30 insertions(+), 15 deletions(-) diff --git a/pep-3156.txt b/pep-3156.txt index c2c32c795..63bf9e33a 100644 --- a/pep-3156.txt +++ b/pep-3156.txt @@ -514,6 +514,8 @@ user code that returns a Future?) A ``tulip.Future`` object is not acceptable to the ``wait()`` and ``as_completed()`` functions in the ``concurrent.futures`` package. +However, there are similar APIs ``tulip.wait()`` and +``tulip.as_completed()``, described below. A ``tulip.Future`` object is acceptable to a ``yield from`` expression when used in a coroutine. This is implemented through the @@ -752,18 +754,40 @@ Things a coroutine can do: produce a result (or raise an exception, which will be propagated). The ``coroutine`` expression must be a *call* to another coroutine. -- ``results = yield from tulip.par(futures_and_coroutines)`` -- Wait - for a list of futures and/or coroutines to complete and return a - list of their results. If one of the futures or coroutines raises - an exception, that exception is propagated, after attempting to - cancel all other futures and coroutines in the list. - - ``return result`` -- produce a result to the coroutine that is waiting for this one using ``yield from``. - ``raise exception`` -- raise an exception in the coroutine that is waiting for this one using ``yield from``. +To wait for multiple coroutines, two APIs similar to the ``wait()`` +and ``as_completed()`` APIs in the ``concurrent.futures`` package are +provided: + +- ``tulip.wait(fs, ...)``. Wait for the Futures or coroutines given + by ``fs`` to complete. This is a coroutine whose result on success + is a tuple of two sets of Futures, ``(done, not_done)``. Optional + arguments ``timeout`` and ``return_when`` have the same meaning and + defaults as for ``concurrent.futures.wait()``. The constants + ``FIRST_COMPLETED``, ``FIRST_EXCEPTION``, ``ALL_COMPLETED`` are + defined with the same values and the same meanings as in PEP 3148. + +- ``as_completed(fs, ...)``. Return an iterator whose values are + coroutines; waiting for successive values waits until the next + Future or coroutine from the set ``fs`` completes, and returns its + result (or raises its exception). The optional argument ``timeout`` + has the same meaning and default as it does for + ``concurrent.futures.wait()``; if the timeout is reached, the next + coroutine will raise ``concurrent.futures.TimeoutError`` when waited + for. Example of use:: + + for f in as_completed(fs): + result = yield from f + +(TBD: should ``as_completed()`` return an iterator of coroutines or an +iterator of Futures? For ``wait()`` it's clear that the sets should +only contain Futures; but less so for ``as_completed()``.) + Calling a coroutine does not start its code running -- it is just a generator, and the coroutine object returned by the call is really a generator object, which doesn't do anything until you iterate over it. @@ -789,10 +813,6 @@ that it may catch to further handle cancellation, but it doesn't have to (this is done using the standard ``close()`` method on generators, described in PEP 342). -The ``par()`` function described above runs coroutines in parallel by -converting them to Tasks. (Arguments that are already Tasks or -Futures are not converted.) - Tasks are also useful for interoperating between coroutines and callback-based frameworks like Twisted. After converting a coroutine into a Task, callbacks can be added to the Task. @@ -819,11 +839,6 @@ Sleeping TBD: ``yield sleep(seconds)``. Can use ``sleep(0)`` to suspend to poll for I/O. -Wait for First --------------- - -TBD: Need an interface to wait for the first of a collection of Futures. - Coroutines and Protocols ------------------------