Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Could the concepts of cancellation, closure, and unsubscription be merged? #23

Open
dead-claudia opened this issue Jan 20, 2019 · 2 comments

Comments

@dead-claudia
Copy link

This is really a shot in the dark, and I expect some initial resistance, but hear me out on this one.

I was thinking you could merge cancelling a request with closing a socket. I know these are two separate concepts, but they are heavily intertwined in practice.

  • When you cancel a request, you frequently are also closing a socket of some kind. This won't come up often in the browser since it's all done in C++ land, but in Node and other environments that define the sockets mostly in JS, that cancel token would be closing the socket alongside the request.
  • When you close a stream, if that stream is more than a simple read/map/write pipeline, it's often also performing async tasks that you might wish to cancel. When reading these streams, you may have to await the next buffer as well, and being able to cancel that request, too, would be nice. So instead of creating a new synthetic cancel token, you could just pass around the same one you received to all places that need it.

This also extends to observables: you could subscribe with a close token instead of just subscribing and receiving an object with an unsubscribe() method and a close property - the close token would already have this info for you.

Also, informally, I've seen these used quite interchangeably, with a heavy bias towards "close":

  • I've heard "close a request", "cancel a request", and "unsubscribe from a request" all three used interchangeably in numerous circles, ranging from IT professionals to seasoned web developers.
  • I've heard "close a stream" and occasionally "abort a stream" or "unsubscribe from a stream" with reference to various streams of data from an even broader group of people. The last is mostly used for when you don't control the stream, but the first two seem preferred in my experience when you control the stream.
  • I've heard "close a subscription", "cancel a subscription", and "unsubscribe from an observable" all three interchangeably among web devs, with the first two common even among non-technical people.

You probably notice I went from "cancel token" to "close token", talking about "closure" instead of "cancellation", and that's on purpose: I'm thinking you could merge cancellation and stream closure to a more abstract "close" operation. You could keep the existing cancel token API or something similar, but I feel there's a lot to be gained by having only one concept instead of 3.

  • Any syntax assist would benefit all three variants, not just promises.
  • There's a sharply reduced need to split them apart and recombine them when dealing with streams for data processing.
  • More complex observables and userland streams could have much simpler closure semantics - they could mostly do the right thing implicitly, up to and including cancelling requests and child observables/streams.
@benjamingr
Copy link

It's all the concept of being "done" with something. The only big difference is between disinterest (I am no longer interested in X) and "destroy" (X needs to stop now) semantics.

As long as we all agree on the former - whether we call it cancel, close, dispose, unsubscribe, complete or anything else that says "we are no longer interested in this thing" - it doesn't actually matter that much.

I also don't think that's why this proposal isn't moving forward right now.

@dead-claudia
Copy link
Author

@benjamingr

It's all the concept of being "done" with something. The only big difference is between disinterest (I am no longer interested in X) and "destroy" (X needs to stop now) semantics.

As long as we all agree on the former - whether we call it cancel, close, dispose, unsubscribe, complete or anything else that says "we are no longer interested in this thing" - it doesn't actually matter that much.

The reason I filed this issue is because these two concepts, signaling disinterest and requesting termination, are often hand-in-hand. I was suggesting that this proposal focus on being "done" in general, rather than the reason why we're "done", because in my experience, those two reasons end up crossing paths more often than not in the face of composition, especially from "disinterest" to "destroy", due to resource leak prevention. For example:

  • If you signal disinterest to a request, it needs to tell the stream to stop emitting data, the server to stop sending data, and the OS to release the file descriptor, to avoid leaking data and wasting CPU and network resources.
  • Similarly, when you wish to stop updating a value based on server data, you can just signal disinterest to the long polling loop, because you just care about the last value you received. It doesn't matter if it's no longer up to date.

It's not so much an academic thing as much as a pragmatic "I'd like to have only one way of doing things, one that integrates with things better" thing.

It's worth noting that languages with explicit destructors, like C++ destructors, Swift's deinit, and Rust's Drop trait implementations but not like Java's .finalize() or Python's __del__, idiomatically use them as more of a generic "done" method than an explicit "destroy" method. So there's some language precedent already. (I know most of those also encourage RAII, but notably Swift doesn't, so it could stand as pretty strong precedent here.)

I also don't think that's why this proposal isn't moving forward right now.

I'm aware, and I wasn't trying to imply such. Sorry if this wasn't clear.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants