A minimalist/extensible lib to handle failures and retries in a gracefull way.
I wanted a few things:
Right now it has 3 default RetryStrategies implementations (it's a protocol):
delay-runner
max-runner
delay-runner-ch
each run
takes a runner
instance and options, which can be
:success
: by default identity
- function called on successfull return:error
: by default noop
- function called on intermediary error:failure
: by default #(throw %) - function called when the run failedWe also supply logging-callbacks
that does the same as
default-callbacks
but logs everything as a tuple of [state, return-or-error]
.
Enough words, code:
(use 'qbits.checkmate)
;; the default
;; after 10 failed tries without pause it'll retrow last error
(run max-runner #(do something that might fail))
;; in fact this translates to
(run max-runner
#(do something that might fail)
{:max 10 ;; try max 10 times
:success (fn [ret] ret) ;; just return value if ok
:failure #(throw %) ;; throw on failure after 10 tries
:error identity}) ;; do nothing in intermediate failures
This is quite simple, unobtrusive, you can add metrics/reporting easily on top of that.
The other strategy takes a seq of delays:
(run delay-runner {:delays (take 50 (exponential-backoff 100))})
(run delay-runner {:delays (take 20 (constant-backoff 100))}) ;; try every 100ms
(run delay-runner {:delays (sane-backoff)})
;; etc
Delays must just be a (potentially infinite) lazy seq of ms, super easy to generate manipulate.
The 3 shown before are just:
(defn constant-backoff [ms]
(repeat ms))
(defn exponential-backoff [x]
(iterate #(* Math/E %) x))
(defn sane-backoff [x]
(lazy-cat
(repeat x 100)
(repeat x 500)
(repeat x 1500)
(repeat x 15000)
(repeat x 60000)))
There's an equivalent of delay-runner
but that runs in a async/go
context, delay-runner-ch
, so timeouts are a bit cheaper, just make
sure your task is non blocking if you don't want to starve the
core.async threadpool. The arguments are identical otherwise.
The whole lib is under 100 lines, easy to understand, modify, extend.
checkmate is available on Clojars.
Copyright © 2016 Max Penet
Distributed under the Eclipse Public License, the same as Clojure.
Can you improve this documentation?Edit on GitHub
cljdoc is a website building & hosting documentation for Clojure/Script libraries
× close