[Python-ideas] async: feedback on EventLoop API

Guido van Rossum guido at python.org
Mon Dec 17 22:01:35 CET 2012


On Mon, Dec 17, 2012 at 12:33 PM, Ronan Lamy <ronan.lamy at gmail.com> wrote:
> Le 17/12/2012 17:47, Guido van Rossum a écrit :
>
>> (BTW, can someone *please* come up with a better name for DelayedCall?
>> It's tedious and doesn't abbreviate well. But I don't want to name the
>> class 'Callback' since I already use 'callback' for function objects
>> that are used as callbacks.)
>
> It seems to me that a DelayedCall is nothing but a frozen, reified function
> call. That it's a reified thing is already obvious from the fact that it's
> an object, so how about naming it just "Call"? "Delayed" is actually only
> one of the possible relations between the object and the actual call - it
> could also represent a cancelled call, or a cached one, or ...

Call is not a bad suggestion for the name. Let me mull that over.

> This idea has some implications for the design: in particular, it means that
> .cancel() should be a method of the EventLoop, not of Call. So Call would
> only have the attributes 'callback' (I'd prefer 'func' or similar) and
> 'args', and one method to execute the call.

Not sure. Cancelling it must set a flag on the object, since the
object could be buried deep inside any number of data structures owned
by the event loop: e.g. the ready queue, the pollster's readers or
writers (dicts mapping FD to DelayedCall), or the timer heap.

When you cancel a call you don't immediately remove it from its data
structure -- instead, when you get to it naturally (e.g. its time
comes up) you notice that it's been cancelled and ignore it. The one
place where this is awkward is when it's a FD reader or writer -- it
won't come up if the FD doesn't get any new I/O, and it's even
possible that the FD is closed. (I don't actually know what epoll(),
kqueue() etc. do when one of the FDs is closed, but none of the
behaviors I can think of are particularly convenient...) I had thought
of giving the DelayedCall a 'cancel callback' that is used if/when it
is cancelled, and for readers/writers it could be something that calls
remove_reader/writer with the right FD. (Maybe I need multiple
cancel-callbacks, in case the same object is used as a callback for
multiple queues.)

Hm, this gets messy.

(Another think in this area: pyftpdlib's event loop keeps track of how
many calls are cancelled, and if a large number are cancelled it
reconstructs the heap. The use case is apparently registering lots of
callbacks far in the future and then cancelling them all. Not sure how
good a use case that it. But I admit that it would be easier if
cancelling was a method on the event loop.)

PS. Cancelling a future is a different thing. There you still want the
callback to be called, you just want it to notice that the operation
was cancelled. Same for tasks.

-- 
--Guido van Rossum (python.org/~guido)



More information about the Python-ideas mailing list