Cancellation architectural observations
jonas at sicking.cc
Mon Mar 2 23:52:26 UTC 2015
On Sun, Mar 1, 2015 at 11:06 PM, Dean Tribble <tribble at e-dean.com> wrote:
> Cancel requests, not results
> Promises are like object references for async; any particular promise might
> be returned or passed to more than one client. Usually, programmers would be
> surprised if a returned or passed in reference just got ripped out from
> under them by another client. this is especially obvious when considering a
> library that gets a promise passed into it. Using "cancel" on the promise is
> like having delete on object references; it's dangerous to use, and
> unreliable to have used by others.
I do wonder if there are two types of "cancelling". Which I think
several of the posts in this thread has touched on.
On one hand there are operations like read requests from the
filesystem, side-effect free GET requests from the network, and
computation requests such as calculating the SHA-256 value of a large
In all of these instances the operation has no side effects other than
producing the value that the promise resolves to.
The second category is operations that do have side effects. Such as a
writing operation to a filesystem or a database, or a POST network
(For now ignoring the fact that some GET requests do have side
effects, and some POST requests don't).
The second category seems simpler. Here it's clear that a lack of
interest in the result does not mean that any requests can or should
be cancelled. An approach like a cancellation token definitely seems
For the first category, a lack of interest in the result means that we
should abort all requests involved in producing that result.
For stream-like APIs we've sort of taken this for granted. Once
back-pressure, or a call to .close() (or similar), indicates that data
is currently not being consumed, the API automatically signals to all
producers that they can and should stop producing results.
Why should we treat APIs that return a single value, rather than a
stream of values, any differently?
But it requires knowing that *no one* is interested in the result.
Simply having access to a Promise object does not guarantee that due
to Promises nature that you can not only call .then() multiple times,
the time when calling .then() is permitted is unbounded.
So I think I'm persuaded by the argument that as long as an API
returns a Promise, there is no way that we can put a
cancellation/result-ignoring/close() API on that Promise. It seems to
simply break the Promise contract.
Instead we'd need to return some object which allows us to track
consumers. I.e. where if you call a .then-like function, you prevent
anyone else from doing so. And if you want to enable others to consume
the result, you have to first fork the result and then call the
.then-like function on your fork.
Unfortunately that .then-like function probably can't be called "then"
given the elevated status that Promises has given that function name.
More information about the es-discuss