-
Notifications
You must be signed in to change notification settings - Fork 9
/
retry.clj
63 lines (54 loc) · 1.74 KB
/
retry.clj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
(ns goose.retry
(:require
[goose.defaults :as d]
[goose.utils :as u]
[clojure.tools.logging :as log]))
(defn default-error-handler
"Default error handler of a Job.
Called when a job fails.
Logs exception & job details."
[_error-service-config job ex]
(log/error ex "Job execution failed." job))
(defn default-death-handler
"Default death handler of a Job
Called when a job fails & has exhausted retries.
Logs exception & job details."
[_error-service-config job ex]
(log/error ex "Job retries exhausted." job))
(defn default-retry-delay-sec
"Calculates backoff seconds
before a failed Job is retried."
[retry-count]
(+ 20
(* (rand-int 20) (inc retry-count))
(reduce * (repeat 4 retry-count)))) ; retry-count^4
(def default-opts
"Default config for Error Handling & Retries."
{:max-retries 27
:retry-delay-sec-fn-sym `default-retry-delay-sec
:retry-queue nil
:error-handler-fn-sym `default-error-handler
:skip-dead-queue false
:death-handler-fn-sym `default-death-handler})
(defn- prefix-retry-queue
[retry-opts]
(if-let [retry-queue (:retry-queue retry-opts)]
(assoc retry-opts :ready-retry-queue (d/prefix-queue retry-queue))
retry-opts))
(defn ^:no-doc prefix-queue-if-present
[opts]
(->> opts
(prefix-retry-queue)))
(defn- failure-state
[{{:keys [retry-count first-failed-at]} :state
:as _job}
ex]
{:error (str ex)
:last-retried-at (when first-failed-at (u/epoch-time-ms))
:first-failed-at (or first-failed-at (u/epoch-time-ms))
:retry-count (if retry-count (inc retry-count) 0)})
(defn set-failed-config
[job ex]
(assoc
job :state
(failure-state job ex)))