leonoel / missionary

A functional effect and streaming system for Clojure/Script
Eclipse Public License 2.0
620 stars 25 forks source link

Recommended basic task usage in production #105

Open yenda opened 3 months ago

yenda commented 3 months ago

While experimenting with missionary, I came accross an issue with taoensso.timbre logging. When logging in the success or error continuation function in a complex enough flow, the log would almost never appear on success/error. It turned out that timbre does a bit of blocking at some point while getting the hostname and according to the task spec the limitations of the continuation functions are:

  • don't block the thread
  • don't throw exceptions
  • return quickly

So timbre but any code unsuspectedly breaking that contract will have undefined behavior.

This means that while having a println or tap in your continuation functions when experimenting with a task in the repl is fine, the recommended way in production to handle success/failure is to run the root of the supervision tree with

(task (constantly nil) (constantly nil))

and if you want to do something on success:

(defn task []
  (m/sp 
     (let [res (m/? (actual-task))] 
       (m/? (on-success res)))

on failure:

(defn task []
  (m/sp 
    (try
      (m/? (actual-task))
      (catch Exception e
         (log/error "OOPS"))