better protect transaction history polling from errors

Go blocks parse try catch blocks and turn them into event
dispatches. This captures the original intent of the code to catch
errors and terminate the current async worker execution.

Signed-off-by: yenda <eric@status.im>
This commit is contained in:
Bruce Hauman 2018-11-20 08:55:31 -05:00 committed by yenda
parent d66198a420
commit a5c5e1831f
No known key found for this signature in database
GPG Key ID: 0095623C0069DCE6
2 changed files with 18 additions and 9 deletions

View File

@ -254,14 +254,23 @@
(defn- async-periodic-exec (defn- async-periodic-exec
"Periodically execute an function. "Periodically execute an function.
Takes a work-fn of one argument `finished-fn -> any` this function Takes a work-fn of one argument `finished-fn -> any` this function
is passed a finished-fn that must be called to signal that the work is passed a finished-fn that must be called to signal that the work
being performed in the work-fn is finished. being performed in the work-fn is finished.
The work-fn can be forced to run immediately " Returns a go channel that represents a way to control the looping process.
Stop the polling loop with `async-periodic-stop!`
The work-fn can be forced to run immediately with `async-periodic-run!`
Or you can queue up another fn `finished-fn -> any` to execute on
the queue with `async-periodic-run!`."
[work-fn interval-ms timeout-ms] [work-fn interval-ms timeout-ms]
{:pre [(fn? work-fn) (integer? interval-ms) (integer? timeout-ms)]} {:pre [(fn? work-fn) (integer? interval-ms) (integer? timeout-ms)]}
(let [do-now-chan (async/chan (async/sliding-buffer 1))] (let [do-now-chan (async/chan (async/sliding-buffer 1))
try-it (fn [exec-fn catch-fn] (try (exec-fn) (catch :default e (catch-fn e))))]
(go-loop [] (go-loop []
(let [timeout (async-util/timeout interval-ms) (let [timeout (async-util/timeout interval-ms)
finished-chan (async/promise-chan) finished-chan (async/promise-chan)
@ -269,12 +278,12 @@
worker (if (and (= ch do-now-chan) (fn? v)) worker (if (and (= ch do-now-chan) (fn? v))
v work-fn)] v work-fn)]
(when-not (and (= ch do-now-chan) (nil? v)) (when-not (and (= ch do-now-chan) (nil? v))
(try ;; don't let try catch be parsed by go-block
(worker #(async/put! finished-chan true)) (try-it #(worker (fn [] (async/put! finished-chan true)))
;; if an error occurs in work-fn log it and consider it done (fn [e]
(catch :default e (log/error "failed to run transaction sync" e)
(log/error "failed to run transaction sync" e) ;; if an error occurs in work-fn log it and consider it done
(async/put! finished-chan true))) (async/put! finished-chan true)))
;; sanity timeout for work-fn ;; sanity timeout for work-fn
(async/alts! [finished-chan (async-util/timeout timeout-ms)]) (async/alts! [finished-chan (async-util/timeout timeout-ms)])
(recur)))) (recur))))

View File

@ -104,7 +104,7 @@
(swap! state inc) (swap! state inc)
(throw (ex-info "Throwing this on purpose in error-in-job test" {}))) (throw (ex-info "Throwing this on purpose in error-in-job test" {})))
10 10
10)) 100))
(async test-done (async test-done
(js/setTimeout (js/setTimeout
(fn [] (fn []