Fork me on GitHub
#core-async
<
2022-11-23
>
Benjamin16:11:28

Hello my use case is I want to start some long running process on the server and signal the client with something like "pending" to say "retry the same request later and you get a result". Then I want to hold on to the result for a few minutes or something

Benjamin16:11:35

(def result-cache
  "request -> result-promise channel."
  (atom {}))

(defn send*
  "Call `f` with `r` on a thread.
  Assoc a result promise-chan on `a` (an atom).
  Dissoc the result 5min after completion."
  [a r f]
  (let [prom (a/promise-chan)]
    (a/thread
      (let [result (try (f r) (catch Throwable t {:error (ex-data t)}))]
        (a/>!! prom result))
      (a/go
        (a/<! (a/timeout (* 1000 60 5)))
        (swap! a dissoc r)))
    (swap! a assoc r prom)))

(defn poll-result!
  "Returns the current result of the result promise.
  "
  [request f]
  (let [prom
        (@result-cache request)
        result (when prom (a/poll! prom))]
    (cond
      result result
      prom :running
      :else
      (do
        (send* result-cache request f)
        :started))))