Skip to content

Cancellation API as a first-class citizen? #167

Open
@kachayev

Description

@kachayev

The idiomatic way to "cancel" deferred in Manifold is to put an error value in order to short-circuit all chained listeners. Recently we had quite a few questions around this specific functionality... So, I wonder if it's better to have a public API in place to deal with cancellation? E.g.

;; define an exception class to be used in case we want to cancel a deferred
(d/CancelledException.)

;; equivalent to (d/error! d (d/CancelledException.)) 
(d/cancel! d)

;; or if I want to use my own subclass
(d/cancel! d (CustomCancelledException.))

;; to check if it was cancelled
(d/cancelled? d)

We also need to document that cancellation of d/future or d/future-with does not interrupt the underlying thread (which would be expected because of future-cancel semantic from Clojure core).

More advanced thins in terms of cancellations:

  1. Versions of d/zip and d/alt that propagate cancellation to underlying deferreds.
(let [ring1 (http/get "rings")
      ring2 (http/get "rings")
      ring3 (http/get "rings")
      one-ring-to-rule-them-all (d/zip-cancellable ring1 ring2 ring3)]
  ;; cancel all 3 http requests, not only the result
  (d/cancel! one-ring-to-rule-them-all))

It might be simple for 2 mentioned functions... but maybe we can think of a more general approach/solution where we can manually specify (or automatically derive?) a graph of connections between different deferred to use it to propagate CancelledExceptions properly?

  1. Keeping in mind previous item... should we treat TimeoutException as a cancellation?

  2. Self-referencial cancelled? checker for d/future. That's arguable, but often times I need this:

(d/future
  (dotimes [_ 100]
    (when-not (am-I-cancelled?)
      (do-something-useful)))) 

I'm not sure about this specific feature as it undercovers underlying mechanics to some extent. It's still doable by introducing a separate deferred in a lexical scope, but this approach might not be obvious for beginners. So, at least it should be well-documented.

@ztellman WDYT?

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions