Asyncio tasks getting cancelled

Ian Kelly ian.g.kelly at gmail.com
Mon Nov 5 15:57:56 EST 2018


On Mon, Nov 5, 2018 at 8:41 AM <ike at koeln.ccc.de> wrote:
> > > But anyway, I highly recommend you to use the "await other_coroutine()"
> > > syntax I talked about earlier. It may even fix the issue (90% chance).
> >
> > This should indeed fix the issue, but this is definitely not what one is
> > looking for if one really want to _schedule_ a coroutine.
>
> Which is what I want in this case. Scheduling a new (long-running) task
> as a side effect, but returning early oneself. The new task can't be
> awaited right there, because the creating one should return already.

If you want to do this in the asyncio.run main coroutine, then that
seems like a problematic design. Once the main coroutine returns, the
event loop should be considered no longer running, and any still
pending callbacks or futures won't resolve.

> > If the goal here is for the task created by main() to complete before
> > the loop exits, then main() should await it, and not just create it
> > without awaiting it.
>
> So if this happens somewhere deep in the hirarchy of your application
> you would need some mechanism to pass the created tasks back up the
> chain to the main function?

I haven't used asyncio.run yet myself, so take all this with a grain
of salt, but it seems to me that anything that you want to resolve
before the event loop terminates should be awaited either directly or
indirectly by the main coroutine. From the documentation:

"""
This function always creates a new event loop and closes it at the
end. It should be used as a main entry point for asyncio programs, and
should ideally only be called once.
"""

So I think part of the idea with this is that the asyncio.run main
coroutine is considered the main function of your async app. Once it
returns, the program should be effectively done. For example, maybe
the main coroutine spins up a web server and returns when the web
server shuts down.

If that doesn't suit your program, for instance there's no core task
to await, but you want to schedule a lot of things that need to
resolve and that the main coroutine has no way to know about, then it
may be the case that asyncio.run is not right for your use case and
you should use loop.run_forever() instead. You'll still need some
criteria for figuring out when to exit though, and it seems to me that
whatever that is you could just bundle it up in a coroutine and await
it from main.



More information about the Python-list mailing list