leonoel/missionary

Recommended basic task usage in production

Closed this issue · 3 comments

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"))

@yenda I have a lot of crashes in my app because using timbre logging with missionary. But telemere logging (the successor to timbre) is not having this problem.

Just referencing #107 and #115 as possibly related.

@yenda @awb99 As of b.41, both issues are fixed so it should not be possible to observe user code running on an interrupted thread. If you still experience issues with timbre, please report and re-open the ticket.