dvlsg/async-csp

What's the best way to cancel things?

Opened this issue · 5 comments

What's the recommended way to make cancellable sort of scenarios in an application with async-csp? Basically, suppose we've got any number of things waiting for output from a channel, but the user clicks a "cancel" button. Are there any recommended patterns for cancellation?

dvlsg commented

Depends on what you want to do with any existing / waiting data. Channel#close() will prevent any new values from showing up. Are you looking to ignore any takes which are still waiting on the channel and just send the sentinel (done) value to them instead?

Are you looking to ignore any takes which are still waiting on the channel and just send the sentinel (done) value to them instead?

Yeah, I think so, so that if something is waiting on a value from take(), then canceling could immediately send the done sentinel so that processes can continue immediately without waiting for the take Promise.

Is something like that already doable?

I'm currently working on a way to organize animation states and transitions, and I'd like for them to be cancellable.

I know I can just use plain promises, and reject things with "sentinel" values, but as you imagine, doing it that way would get messy.

I'm wondering if there's a clean way of organizing this with channels.

I know I can send anything I want through a channel, so I can design my own "sentinel" values to tell the receiving end what's going on.

Let me play with it and see what I come up with using the existing public API

dvlsg commented

My gut is telling me to suggest using Channel#close() and then keep an eye out for that Channel.DONE symbol in any Channel#take() calls, but you won't be able to re-use the channel, in that case. Right now, you'd have to set up another one.

The call to take() will resolve, so you'd still have to wait for it (sort of), but it won't wait for new values to come into the channel -- all outstanding takes should resolve with the Channel.DONE value ASAP, even if there are a bunch queued up.

dvlsg commented

Probably the best way of doing it, yes. Shouldn't be too difficult to make an api which appends / returns a newly piped channel when a new consumer shows up. I think Channel#unpipe() and Channel#close() might help you with destructing those connections as well (if necessary). But yes, Channels are not multi-cast / fan out (by design).