tractor icon indicating copy to clipboard operation
tractor copied to clipboard

Injecting `Context._scope: trio.Nursery` errors, probably a `ContextCancelled` to start

Open goodboy opened this issue 2 years ago • 0 comments

Writing up some much more detailed tests for remote actor cancellation as part of #357 has me thinking again about how it'd be nice to be able to inject our own subtype of .trio.Cancelled into each internal nursery / scope (on each side of an inter-actor-task context).

That is @tractor.context and Context.open_context() tasks raise a ContextCancelled on their next checkpoint when our runtime desires to indicate a cancellation condition that was triggered by either Actor.cancel_actor() or Context.cancel() (and/or error bubbling over IPC?) from one side to the other. This would in theory make cross process task supervision easier to implement as well as make it possible to allow the @context side task able to handle remote cancellation requests (more) granular-ly and possibly specially?

A further handy use case would be overriding the CancelScope.__exit__() to allow hiding its stack frame in the pdb repl; something that's handy if you want to shield a pause point like:

trio.CancelScope(shield=True):
  await tractor.pause()

and hide the exit frame on REPL initial entry. (at least this seemed to still be a problem last time i tried to implement such a thing doing .pause(shield=True))


Gitter community suggestions

(Mostly from @oremanj yet again :joy:)

  • possibly adding a Task.interrupt_with_exception(ContextCancelled) to make a public API equivalent of Task._attempt_abort()?

    • applying this approach to a whole cancel scope - this is probably not the right abstraction (level)

    • there have been periodic discussions about how to indicate the 'type' of a cancellation, and I think that would be a better fit for your use case. then all the other tasks in the nursery will see a normal Cancelled as the exception passes through the nursery and causes them to be cancelled. if you want this to behave like a normal Trio cancellation then it needs to hook into the cancellation mechanism, not the abort mechanism, IMO. (this is what we use to deliver KI). yeah, abort can only be used to wake up a task that is currently blocked.

  • at the very least it'd be handy to be able to mutate/augment the Cancelled type for such a thing instead of having to touch the entire cancellation system?


ToDo:

  • [ ] write up some basic @tractor.context use cases and see if they even really need or make sense having a special ContextCancelled raised.
    • for me making class contextCancelled(Cancelled): prolly makes the most sense since you can keep all normal exception semantics in place but allow code to specially handle the case where the cancellation is due to our runtime's cancellation API versus something in the client-app code which is *built on tractor.

goodboy avatar Oct 19 '23 18:10 goodboy