Recipe request: asyncio "spin off coroutine"

Frank Millman frank at chagford.com
Thu Dec 15 00:39:59 EST 2016


"Chris Angelico"  wrote in message 
news:CAPTjJmoFyJqYw4G_kNo5Sn=ULyjgm=KeXqrQVWUBr87EVbzAFA at mail.gmail.com...
>
> When you work with threads, it's pretty straight-forward to spin off
> another thread: you start it. Your current thread continues, and the
> other one runs in parallel.
>
> What's the most straight-forward way to do this in asyncio?
>

You have got the answer - asyncio.ensure_future(...)

I thought I would share something that happened just yesterday, where this 
came to my rescue.

I mentioned in a recent post that I had set up a background task to process 
HTTP requests for a given session, using an asyncio.Queue and an endless 
loop.

I have a session.close() coroutine which has, among other steps -
    await self.request_queue.put(None)  # to stop the loop
    await self.request_queue.join()  # to ensure all requests completed

There are three places in my code that can await session.close() -

    - on closing the program, close all open sessions
    - on detecting that the session is no longer responding, kill the 
session
    - on receiving a message from the client indicating that it had closed

The first two worked fine, but the third one hung. I eventually found that, 
because I was awaiting session.close() from within the request handler, that 
request had not completed, therefore it was hanging on the 'join'.

I was stumped for a while, and then I had an 'aha' moment.

I changed 'await self.close()', to 'asyncio.ensure_future(self.close())'.

Problem solved.

Frank Millman






More information about the Python-list mailing list