with-retry-exponential-backoff
Clojure
(defn with-retry
"Calls f until it succeeds, retrying with capped exponential backoff and jitter."
[f {:keys [attempts base-ms max-ms] :or {attempts 5 base-ms 100 max-ms 5000}}]
(loop [n 0]
(let [result (try {:ok (f)} (catch Exception e {:err e}))]
(if (:ok result)
(:ok result)
(if (>= n (dec attempts))
(throw (:err result))
(let [cap (min max-ms (* base-ms (bit-shift-left 1 n)))
pause (+ (quot cap 2) (rand-int (inc cap)))]
(Thread/sleep pause)
(recur (inc n))))))))