Asyncio tasks getting cancelled
Ian Kelly
ian.g.kelly at gmail.com
Mon Nov 5 01:55:47 EST 2018
On Sun, Nov 4, 2018 at 3:58 PM Léo El Amri via Python-list
<python-list at python.org> wrote:
>
> On 04/11/2018 20:25, ike at koeln.ccc.de wrote:
> > I'm having trouble with asyncio. Apparently tasks (asyncio.create_task)
> > are not kept referenced by asyncio itself, causing the task to be
> > cancelled when the creating function finishes (and noone is awaiting the
> > corresponding futue). Am I doing something wrong or is this expected
> > behavior?
> >
> > The code sample I tried:
> >
> >> import asyncio
> >>
> >> async def foobar():
> >> print(1)
> >> await asyncio.sleep(1)
> >> print(2)
> >>
> >> async def main():
> >> asyncio.create_task(foobar())
> >> #await asyncio.sleep(2)
> >>
> >> loop = asyncio.get_event_loop()
> >> asyncio.run(main())
> >> loop.run_forever()
> >
>
> I don't know anything about asyncio in Python 3.7, but given the
> documentation, asyncio.run() will start a loop and run the coroutine
> into it until there is nothing to do anymore, then free the loop it
> created. I assume it's kind of a run_forever() with some code before it
> to schedule the coroutine.
My understanding of asyncio.run() from
https://github.com/python/asyncio/pull/465 is that asyncio.run() is
more or less the equivalent of loop.run_until_complete() with
finalization, not loop.run_forever(). Thus this result makes sense to
me: asyncio.run() runs until main() finishes, then stops. Without the
sleep(2), main() starts creates the foobar() task and then returns
without awaiting it, so the sleep(1) never finishes. asyncio.run()
also finalizes its event loop, so I assume that the loop being
run_forever must be a different event loop since running it doesn't
just raise an exception. Therefore it doesn't resume the foobar()
coroutine since it doesn't know about it.
Combining asyncio.run() with loop.run_forever() makes little sense.
The purpose of asyncio.run() as I understand it is to avoid having to
manage the event loop oneself.
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.
More information about the Python-list
mailing list