[New-bugs-announce] [issue26923] asyncio.gather drops cancellation

Johannes Ebke report at bugs.python.org
Tue May 3 08:50:06 EDT 2016


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 <report at bugs.python.org>
<http://bugs.python.org/issue26923>
_______________________________________


More information about the New-bugs-announce mailing list