New submission from Johannes Ebke:
In a very specific case, asyncio.gather causes a cancel() call on the Task
waiting on the _GatheringFuture to return a false positive. An example program
demonstrating this is attached.
The context: asyncio.gather creates a _GatheringFuture with a list of child
Futures. Each child Future carries a done callback that updates the
_GatheringFuture, and once the last child done callback is executed, the
_GatheringFuture sets its result.
The specific situation: When the last child future changes state to done it
schedules its done callbacks, but does not immediately execute them. If the
Task waiting on the gather is then cancelled before the last child done
callback has run, the cancel method in asyncio/tasks.py:578 determines that the
_GatheringFuture inspects itself and sees that it is not done() yet, and
proceeds to cancel all child futures - which has no effect, since all of them
are already done(). It still returns True, so the Tasks thinks all is well, and
proceeds with its execution.
The behaviour I would expect is that if cancel() is called on the
_GatheringFuture, and all children return False on cancel(), then
_GatheringFuture.cancel() should also return False, i.e.:
def cancel(self):
if self.done():
return False
at_least_one_child_cancelled = False
for child in self._children:
if child.cancel():
at_least_one_child_cancelled = True
return at_least_one_child_cancelled
If I replace _GatheringFuture.cancel with the above variant, the bug disappears
for me.
More context: We hit this bug sporadically in an integration test of aioredis,
where some timings conspired to make it appear with a chance of about 1 in 10.
The minimal example calls the cancellation in a done_callback, so that it
always hits the window. This was not the way the bug was discovered.
----------
components: asyncio
files: cancellation_test.py
messages: 264719
nosy: JohannesEbke, gvanrossum, haypo, yselivanov
priority: normal
severity: normal
status: open
title: asyncio.gather drops cancellation
type: behavior
versions: Python 3.5
Added file: http://bugs.python.org/file42694/cancellation_test.py
_______________________________________
Python tracker <[email protected]>
<http://bugs.python.org/issue26923>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe:
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com