[Python-ideas] Async API

Yury Selivanov yselivanov.ml at gmail.com
Thu Oct 25 01:37:57 CEST 2012


On 2012-10-24, at 7:25 PM, Steve Dower <Steve.Dower at microsoft.com> wrote:
[snip]
> Could another workaround be to spawn the cleanup code without yielding - in effect saying "go and do this, but don't come back"? Then there is nowhere for the scheduler to throw the exception.
> 
> I ask because this falls out naturally with my implementation (code is coming, but work is taking priority right now): "do_cleanup()" instead of "yield do_cleanup()". I haven't tried it in this context yet, so no idea whether it works, but I don't see why it wouldn't. In a system without the @async decorator you'd need a "scheduler.current.spawn(do_cleanup)" instead of yield [from]s, but it can still be done.

Well, yes, this will work.

If we have the following:

    # "async()" is a way to launch coroutines in my framework without 
    # "coming back"; with it they just return a promise/future that needs 
    # to be yielded again
    finally:
        yield c.close().async()

The solution is very limited though.  Imagine if you have lots of cleanup code

    finally:
        yield c1.close().async() # go and do this, but don't come back
        yield c2.close().async()

The above won't work, as scheduler would have an opportunity to break
everything on the second 'yield'.

You may solve it by grouping cleanup code in a separate inner coroutine, 
like:

    @coroutine
    def do_stuff():
        try:
            ...
        finally:
            @coroutine
            def cleanup():
                yield c1.close()
                yield c2.close()

            yield cleanup().async() # go and do this, but don't come back

But that looks even worse than using 'with protect_finally()'.

-
Yury
 




More information about the Python-ideas mailing list