[Python-Dev] [PEP 3148] futures - execute computations asynchronously
P.J. Eby
pje at telecommunity.com
Sun Mar 7 18:57:31 CET 2010
At 08:39 AM 3/7/2010 -0800, Jeffrey Yasskin wrote:
>On Sun, Mar 7, 2010 at 7:48 AM, P.J. Eby <pje at telecommunity.com> wrote:
> > At 02:49 PM 3/7/2010 +1000, Nick Coghlan wrote:
> >>
> >> P.J. Eby wrote:
> >> > (Personally, I think it would be better to just drop the ambitious title
> >> > and scope, and go for the "nice task queue" scope. Â I
> imagine, too, that
> >> > in that case Jean-Paul wouldn't need to worry about it being raised as a
> >> > future objection to Deferreds or some such getting into the stdlib.)
> >>
> >> This may be a terminology thing - to me futures *are* just a nice way to
> >> handle farming tasks out to worker threads or processes. You seem to see
> >> them as something more comprehensive than that.
> >
> > Actual futures are, yes. Â Specifically, futures are a mechanism for
> > asynchronous computation, whereas the PEP seems to be all about
> > synchronously managing parallel tasks. Â That's a huge difference.
> >
> > Technically, the things in the PEP (and by extension, Java's futures) match
> > the letter of the definition of a future, but not (IMO) the
> spirit. Â There's
> > no clean way to compose them, and at base they're more about parallelism
> > than asynchrony.
>
>Do you have an example of a language or library that uses the term
>"future" to refer to what you're talking about? I'm curious to see
>what it looks like.
The wikipedia page menetioned earlier in the discussion has several
examples. Twisted's Deferreds are probably the best example of such
a system in Python, though, as far as I know. The features proposed
in the PEP are basically akin to Twisted's deferToThread(), i.e.
"return a future for running this code in some other thread".
However, you could easily make your own thread or process pool for
executing tasks, using Deferreds as your "future" objects;
deferToThread() is not particularly special, it's just one possible
"executor", to use the PEP's terminology. Likewise, deferreds are
not limited to representing parallel task execution - they can also
represent asynchronous events such as incoming I/O or a waited-for mouse click.
Deferreds allow composing calculation by stacking callbacks (in
continuation-passing style), but they're most Pythonic (IMO) when
used with a coroutine wrapping system like Eventlet or my earlier
peak.events framework, so that you can use them in "yield"
expressions. That way you can write synchronous-looking code that
nonetheless executes asynchronously.
Twisted uses Deferreds extensively, both for I/O and IPC, and of
course for database access. However, the 'defer' module itself is
conceptually distinct from both the I/O system, event loop, and
threads: it's a largely-generic framework for managing asynchronous
computation. Parallel task queueing is simply *one* possible
application of Deferreds; their actual purpose is to provide a common
API for working with values that aren't yet known.
That is to say, futures.
In contrast, the PEP manages only a very limited sort of "future" -
the completion of a single task, which must be synchronously waited
for. If one "future" in the PEP needs to wait for another, you tie
up that thread or process in a busy loop... which rather limits how
much parallelism you can have.
Deferreds also allow you to write code that doesn't *care* whether
the value has been determined or not... you can simply stack on what
code you want to have run when the value is available, and it runs
immediately if the value is there.
Likewise, a deferred is not tied to the execution of a single piece
of code - it's more of a rendezvous or synchronization point, that
can be given a value to "fire" with. (In contrast, the PEP's
"futures" are tightly coupled to a task execution model: they have a
notion of running and being cancelled, for example.)
For these reasons, I'd say that Deferreds are much more deserving of
the title "futures", especially since there is no need to call a
simple task queue a "futures" system. (Unless you're Java, I
suppose, in which case you might want the name for marketing
reasons. ;-) But in Python I assume we'd like to call a spade a
spade, and a task queue a task queue.)
More information about the Python-Dev
mailing list