Re: [Python-Dev] A more flexible task creation

2018年6月15日 01:28:54 -0700

Le 14/06/2018 à 04:09, Nathaniel Smith a écrit :
> How about:
> 
> async def wait_to_run(async_fn, *args):
>   await wait_for_something()
>   return await async_fn(*args)
> 
> task = loop.create_task(wait_to_run(myfunc, ...))
> 
It's quite elegant, although figuring out the wait_for_something() is
going to be tricky.
> -----
> 
> Whatever strategy you use, you should also think about what semantics
> you want if one of these delayed tasks is cancelled before it starts.
> 
> For regular, non-delayed tasks, Trio makes sure that even if it gets
> cancelled before it starts, then it still gets scheduled and runs until
> the first cancellation point. This is necessary for correct resource
> hand-off between tasks:
> 
> async def some_task(handle):
>   with handle:
>     await ...
> 
> If we skipped running this task entirely, then the handle wouldn't be
> closed properly; scheduling it once allows the with block to run, and
> then get cleaned up by the cancellation exception. I'm not sure but I
> think asyncio handles pre-cancellation in a similar way. (Yury, do you
> know?
> 
> Now, in delayed task case, there's a similar issue. If you want to keep
> the same solution, then you might want to instead write:
> 
> # asyncio
> async def wait_to_run(async_fn, *args):
>   try:
>     await wait_for_something()
>   except asyncio.CancelledError:
>     # have to create a subtask to make it cancellable
>     subtask = loop.create_task(async_fn(*args))
>     # then cancel it immediately
>     subtask.cancel()
>     # and wait for the cancellation to be processed
>     return await subtask
>   else:
>     return await async_fn(*args)
> 
> In trio, this could be simplified to
> 
> # trio
> async def wait_to_run(async_fn, *args):
>   try:
>     await wait_for_something()
>   except trio.Cancelled:
>     pass
>   return await async_fn(*args)
> 
> (This works because of trio's "stateful cancellation" – if the whole
> thing is cancelled, then as soon as async_fn hits a cancellation point
> the exception will be re-delivered.)
Thanks for the tip. It schedules it in all cases, but I don't know what
asyncio does with it. I'll add a unit test for that.
_______________________________________________
Python-Dev mailing list
[email protected]
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com

Reply via email to