classification
Title: add method throw() to asyncio.Task
Type: enhancement Stage: resolved
Components: asyncio Versions: Python 3.6
process
Status: closed Resolution: rejected
Dependencies: Superseder:
Assigned To: Nosy List: Oleg K2, asvetlov, yselivanov
Priority: normal Keywords:

Created on 2017-11-21 14:44 by Oleg K2, last changed 2018-05-29 19:15 by yselivanov. This issue is now closed.

Messages (5)
msg306644 - (view) Author: Oleg K (Oleg K2) Date: 2017-11-21 14:44
currently there is no other way to interrupt task but to call
cancel() which will: 

"This arranges for a CancelledError to be thrown into the wrapped coroutine on the next cycle through the event loop."

in order to write advanced Tasks there should be a way
to throw custom exceptions into active Task. 
so it can react accordingly.  

i am looking for the same thing as "generator.throw()" is providing,
allowing to interrupt generators different way.
msg306647 - (view) Author: Yury Selivanov (yselivanov) * (Python committer) Date: 2017-11-21 15:03
> in order to write advanced Tasks there should be a way
> to throw custom exceptions into active Task. 
> so it can react accordingly.  

What is an "advanced" task?  Why CancelledError is not enough?  What's the actual use case?
msg307287 - (view) Author: Oleg K (Oleg K2) Date: 2017-11-30 10:53
What is an "advanced" task?  
Why CancelledError is not enough?  
What's the actual use case?
----------------------

for instance, i want to create a task which is responsible for 
controlling a "slow resource" that should accessed carefully not to DOS it,  
that could be an long running api call,
or report generation procedure, or slow sqlite query.

that task may be interrupted when program needs to respond quickly 
for example UI is requesting another action with that slow resource, 
that should happen asap. 

if i could throw custom exception, that task would  suspend or interrupt 
current action, then execute something new and urgent, and then continue
where it left of. 
-----------------------------------------------------

also there is another case i have in mind, 

there is a task which monitors video stream with different means to see if that stream is alive an fine, it uses external calls to ffmpeg to check how the stream is doing,  -  that monitoring procedure is continuous always running task, 

sometimes there is a network problem or one of CDN servers go down,
when that event is happening i need to throw custom exception to that
 "monitoring task" no matter at which stage it is at.  

when that task will get custom exception it will not exit but will switch to different operation mode, it should not exit because the monitoring is continuous process ,
it just hast to interpret its measurements differently, and use different ways to measure video state.


---

I hope i made clear examples, lmk if you need more details.
thanks!
msg308232 - (view) Author: Andrew Svetlov (asvetlov) * (Python committer) Date: 2017-12-13 19:15
I think the ship has sailed.
Now too many code is based on assumption that the only way to cancel a task from outer code is `task.cancel()`. Internally it is turned into 

try:
   await do_stuff()
except asyncio.CancelledError:
   do_task_cancellation() 

Raising *any* exception for cancellation breaks all existing code like this. Moreover figuring out if a task was cancelled from outside (by timeout for example) or exception was raised by inner code becomes impossible.

I suggest closing the issue with "wont fix" resolution.
msg318071 - (view) Author: Yury Selivanov (yselivanov) * (Python committer) Date: 2018-05-29 19:15
I'm just going to close this as "won't fix".
History
Date User Action Args
2018-05-29 19:15:03yselivanovsetstatus: open -> closed
resolution: rejected
messages: + msg318071

stage: resolved
2017-12-13 19:15:18asvetlovsetnosy: + asvetlov
messages: + msg308232
2017-11-30 10:53:24Oleg K2setmessages: + msg307287
2017-11-21 15:03:47yselivanovsetmessages: + msg306647
2017-11-21 14:44:12Oleg K2create