[Python-ideas] Async API

Yury Selivanov yselivanov.ml at gmail.com
Thu Oct 25 01:03:17 CEST 2012


Hi Guido,

On 2012-10-24, at 6:43 PM, Guido van Rossum <guido at python.org> wrote:

> On Wed, Oct 24, 2012 at 2:30 PM, Greg Ewing <greg.ewing at canterbury.ac.nz> wrote:
>> Yury Selivanov wrote:
>> 
>>> It's not about try..finally nesting, it's about Scheduler being aware
>>> that a coroutine is in its 'finally' block and thus shouldn't be
>>> interrupted
>>> at the moment
>> 
>> 
>> It would be a bad idea to make a close() method, or anything else
>> that might be needed for cleanup purposes, be a 'yield from' call.
>> If it's an ordinary function, it can't be interrupted in the world
>> we're talking about, so the PEP 419 problem doesn't apply.
>> 
>> If I were feeling in a radical mood, I might go as far as suggesting
>> that 'yield' and 'yield from' be syntactically forbidden inside
>> a finally clause. That would force you to design your cleanup
>> code to be safe from interruptions.
> 
> What's the problem with just letting the cleanup take as long as it
> wants to and do whatever it wants? That's how try/finally works in
> regular Python code.

The problem appears when you add timeouts support.

Let me show you an abstract example (I won't use yield_froms, but I'm
sure that the problem is the same with them):

   @coroutine
   def fetch_comments(app):
       session = yield app.new_session()
       try:
            return (yield session.query(...))
       finally:
            yield session.close()

and now we execute that with:

   #: Get a list of comments; throw a TimeoutError if it
   #: takes more than 1 second
   comments = yield fetch_comments(app).with_timeout(1.0)

Now, scheduler starts with 'fetch_comments', then executes
'new_session', then executes 'session.query' in a round-robin fashion.

Imagine, that database query took a bit less than a second to execute,
scheduler pushes the result in coroutine, and then a timeout event occurs.
So scheduler throws a 'TimeoutError' in the coroutine, thus preventing
the 'session.close' to be executed.  There is no way for a scheduler to
understand, that there is no need in pushing the exception right now,
as the coroutine is in its finally block.

And this situation is a pretty common when you have such timeouts 
mechanism in place and widely used.

-
Yury


More information about the Python-ideas mailing list