Can't cancel an awaiting task?

I’m trying to cancel a task that is awaiting on the completion of another future, however this cause the code to abort.

Looking a bit into the code, it seems that AsyncTaskChain::do_remove() (which is called by cancel()) does not remove a task in S_awaiting state.

The cancel()method checks if the task is done after calling remove, and, if not, an assert is triggered.

from panda3d.core import AsyncFuture

future = AsyncFuture()

async def waiting_task():
    await future

async def cancel_task(t):
    print(t.get_state())
    t.cancel()

import direct.directbase.DirectStart

t = taskMgr.add(waiting_task())
taskMgr.add(cancel_task(t))
base.run()

And the output is :

6
Assertion failed: done() at line 465 of panda/src/event/asyncTask.cxx
:task(error): PythonTask cancel_task exception was never retrieved:
Traceback (most recent call last):
  File "test/test_async3.py", line 10, in cancel_task
    t.cancel()
AssertionError: done() at line 465 of panda/src/event/asyncTask.cxx

This is in fact implemented, but only on the master branch, not in 1.10. In 1.10, cancel() is an alias for remove(). On the master branch, it reschedules the task and throws a CancelledException into it.

Thanks for the info! Perhaps it´s time for me to switch to the master branch.

I want to add that I’m not sure whether we yet implemented the behaviour of asyncio, which is (I believe) that the future you’re awaiting inside the cancelled task also gets cancelled (eg. if it’s a cancellable request like a tex.prepare() call, an interval, or a ModelLoadRequest). I actually feel a little ambivalent about whether that should be the right behaviour, but we should probably match what asyncio does.

With asyncio, if you’re awaiting on a future in a task and the task gets cancelled the future is also cancelled (I believe using a call to the cancel() method if I understand correctly asyncio.tasks.Task).

Thanks for confirming. Could you please file a feature request for 1.11 that futures being awaited by a coroutine task should be cancelled if the task is cancelled?

The feature request is Futures being awaited by a coroutine task should be cancelled if the task is cancelled · Issue #1136 · panda3d/panda3d · GitHub

2 Likes