Effect cancellation
On a number of occassions I've ended up implementing domain specific signaling in capabilities for canceling effects. This is especially useful for subscriptions.
There are two directions:
- Shell cancells a subscription, communicating that the stream has eneded
- Core is no longer interested in the subscription (the relevant task has ended)
In the latter case, attempting to resolve the effect again will, I'm pretty sure, result in a panic at the moment, which is not ideal.
It would be good if Crux could automatically signal to the shell that the subscription has been terminated and any related resources on the shell side can be cleaned up.
Just dropping my idea for implementing the core->shell side of this from my chat w/ @charypar
- Each App/Executor/Whatever has a synchronous unbounded MPSC for dead subscriptions
- Each stream gets a sender for that when they start (probably at the point they are first awaited rather than created, though 🤷 whatevers easiest)
- We add a Drop impl to our stream struct that sends a message on the channel
- At the end of each event loop run we look in this channel and create "i'm a dead stream" messages to pass up to the shell
There's probably some details that'd need worked out, but I think the approach would work
Does #279 close this issue and if so will it also update on the roadmap? https://github.com/orgs/redbadger/projects/11
It does not - it only adds cancellation to timers and makes it an explicit part of the time capability protocol. This issue is about supporting this for all effects without the capability having to explicitly implement the cancellation semantics.
Since the command abstraction has been released, the basic cancellation from Core is supported by aborting commands. Resolving aborted effect request is a no-op.
Rust shells can cancel effects by dropping the associated crux_core::Request, which immediately aborts their associated task (since they can't be resolved and continued any more).
The only missing piece is support in the Bridge for cancelling effects by ID.
It's worth saying that for most capabilities, this basic support may not be quite enough, as it doesn't easily allow for resource cleanup on the shell side when effects are cancelled.
An example of how that might work is the new implementation in crux_time. I'm not sure whether there's a generic solution which would allow for this, since the information that needs to be passed alongside the cancellation request is capabilty specific.