This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
- # announcements (2)
- # babashka (26)
- # beginners (48)
- # calva (32)
- # cider (23)
- # clj-kondo (61)
- # cljfx (3)
- # clojure (93)
- # clojure-australia (2)
- # clojure-europe (23)
- # clojure-losangeles (1)
- # clojure-nl (5)
- # clojure-uk (4)
- # clojurescript (46)
- # cloverage (9)
- # code-reviews (1)
- # copenhagen-clojurians (1)
- # cursive (39)
- # data-science (6)
- # datahike (8)
- # deps-new (8)
- # depstar (2)
- # etaoin (1)
- # fulcro (2)
- # funcool (2)
- # graalvm (5)
- # jackdaw (3)
- # java (17)
- # jobs-discuss (43)
- # kaocha (2)
- # leiningen (25)
- # malli (8)
- # minecraft (1)
- # missionary (8)
- # observability (6)
- # off-topic (37)
- # other-languages (12)
- # practicalli (1)
- # reagent (4)
- # releases (78)
- # remote-jobs (1)
- # sci (9)
- # shadow-cljs (13)
- # spacemacs (6)
- # sql (1)
- # tools-deps (24)
- # xtdb (3)
I just noticed that the new cancel exception inherits from Throwable. What's the reasoning for not inheriting from Exception?
because when you need to recover from a domain exception, it is very unlikely that you want to recover from cancellation too
That makes sense. But how do you deal with InterruptedException or other types of cancellations? Currently in my exception handling, I have a
which leads to duplication. I doesn't feel right to catch Throwable, because that catches other more serious exceptions as well. The other option I can think of is to wrap all the via blocks and return a Cancelled exception when the thread is interrupted.
(catch missionary.Cancelled DEAL WITH CANCELLATION) (catch Exception ex (when (ex-cancelled? ex) DEAL WITH CANCELLATION))
If an expression can throw many kinds of exceptions on thread interruption, I would say make it consistent ASAP, preferably on a fine-grained basis.
> I doesn't feel right to catch Throwable, because that catches other more serious exceptions as well.
Exception has the same problem, it includes many serious errors (e.g
I think it's OK to catch with a broad type like
Throwable as long as you rethrow what you don't recover :
(catch Throwable ex (if (ex-cancelled? ex) (DEAL WITH CANCELLATION) (throw ex)))
I think the difference between catching Exception and Throwable is that Throwable includes irrecoverable errors like out of memory/stack overflow. Would it make sense to wrap InterruptedException inside Cancelled within missionary? Currently it feels inconsistent - you can never be sure that missionary.Cancelled is the only cancellation exception you have to catch. For example:
(m/? (m/reduce conj (m/ap (let [n (m/?< (m/seed [1 2]))] (try (m/? (m/sleep 1000)) n (catch missionary.Cancelled _ (println "cancelled")))))))
does not work. In effect you always have to wrap m/via in a try/catch and throw missionary.Cancelled, otherwise the code does not work as expected.
(m/? (m/reduce conj (m/ap (let [n (m/?< (m/seed [1 2]))] (try (m/? (m/via m/cpu (Thread/sleep 1000))) n (catch missionary.Cancelled _ (println "cancelled")))))))
To deal with this issue, I have changed my code to use custom
via macros instead of the missionary
via macros, something like:
Does it make sense to do it this way?
(defmacro via-blk [& body] `(ms/via ms/blk (try [email protected] (catch Exception ex# (if (ex-cancelled? ex#) (throw (missionary.Cancelled. (ex-message ex#))) (throw ex#))))))
> Does it make sense to do it this way?
I think it does.
> Would it make sense to wrap InterruptedException inside Cancelled within missionary?
I considered that,
via is about thread interop so it could intercept
InterruptedException and turn it into
? in thread mode could intercept
missionary.Cancelled and turn it into
InterruptedException. The problem is, nobody is forced to use
InterruptedException, and in practice there's very little consistency in how blocking code reacts to thread interruption (this is the essence of your problem, if I understand correctly). Therefore, I think it's a reasonable choice for missionary not to perform any magic conversion and leave full control to the user.
> Currently it feels inconsistent - you can never be sure that missionary.Cancelled is the only cancellation exception you have to catch.
In general, you can't be sure indeed. But here the inconsistency comes from the code you need to interop with, and only you can make the right decision about it.
On the same topic you can check https://github.com/leonoel/missionary/discussions/57