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.
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?
It’s because the AsyncGatheringFuture::cancel() code assumes that if cancel() on a future returns true, it is really cancelled right then and there; but this is no longer true because calling cancel() on a task only schedules it to be cancelled in the future (and then it may still resist the cancellation).
The solution is to change gather().cancel() to make fewer assumptions.
As for “unexpected task state”, this is a rare corner case: cancelling the task is also causing the gather() to be cancelled, which would be fine if it were taking effect right away, but this happens delayed since it needs to wait for the contained task to (possibly) handle the cancellation. So, the task gets reactivated but then when the gather() finishes being cancelled it tries to also reactivate the task, and gets confused because it is already active. I think I can just handle this with a no-op if the task is already active.
Checked in fixes for both issues to the master branch.
Thanks for the fixes and the explanation ! I made a new build with these fixes and so far I don’t get any errors any more. I will continue stressing the app to see if everything is stable.
Bw, I’m using the coroutine tasks inside a common thread but also across threads and it works as expected for both cases