Fork me on GitHub
#missionary
<
2023-04-14
>
J13:04:44

Hi! it’s possible with missionary to launch a task without blocking the thread like a future (or just use a future in this case) ?

xificurC13:04:03

missionary is agnostic to that. I.e. If you don't have any blocking calls it will not block. If you have a blocking call you should use m/via

xificurC13:04:54

do you have a specific snippet?

J14:04:23

(defn fetch-text []
  (Thread/sleep 2000)
  {:text "A text"})

(defn create-context []
  {:page (future (fetch-text))})

(def ctx (create-context))

;; Later

@(:page ctx)
Is there a way to have a similar behaviour with missionary or it’s not the purpose of missionary and here a future is a better choice?

leonoel14:04:41

so the goal is to run a task once and use the result multiple times ?

leonoel14:04:19

Currently, you can emulate future semantics with dfv :

(def fetch-text (m/sleep 2000 {:text "A text"}))

(defn create-context []
  (let [v (m/dfv)]
    (fetch-text v #(.printStackTrace ^Throwable %))
    {:page v}))

(def ctx (create-context))

(m/? (:page ctx))

leonoel14:04:11

However, this is not a pattern I want to encourage, because it breaks supervision. The solution I have in mind is a new construct called memo which memoizes a task result like future but the underlying process starts lazily and is cancelled when it has no more subscriber, this would look like this :

(defn create-context []
  {:page (m/memo fetch-text)})
More details here https://github.com/leonoel/missionary/issues/70

J14:04:52

Thanks for the info.

J09:04:57

Hi! For the moment, you recommend to use future directly?

leonoel09:04:38

Sorry for confusion. future breaks supervision in the exact same way, so it is exactly as bad as dfv, which is still my current recommendation. Use this pattern https://github.com/leonoel/missionary/wiki/Task-interop#futures-promises-1

leonoel09:04:18

(defn future! [t]
  (let [v (m/dfv)]
    (t #(v (fn [] %)) #(v (fn [] (throw %))))
    (m/absolve v)))

(defn create-context []
  {:page (future! (fetch-text))})

leonoel09:04:26

clojure's future would work too but blocking more threads than needed

J09:04:33

In your example fetch-text is a task, right?

leonoel09:04:01

function returning task

👍 1