-
Notifications
You must be signed in to change notification settings - Fork 6
/
core.clj
90 lines (66 loc) · 2.67 KB
/
core.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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
(ns resilience.core
(:import (io.github.resilience4j.circuitbreaker CircuitBreaker)
(io.github.resilience4j.retry Retry)
(io.github.resilience4j.bulkhead Bulkhead)
(io.github.resilience4j.ratelimiter RateLimiter)
(io.github.resilience4j.timelimiter TimeLimiter)
(java.util.function Supplier)))
;; breaker
(defmacro execute-with-breaker [breaker & body]
(let [breaker (vary-meta breaker assoc :tag `CircuitBreaker)
f (with-meta `(fn [] (do ~@body)) {:tag `Callable})]
`(.executeCallable ~breaker ~f)))
(defn with-breaker [^CircuitBreaker breaker f]
(CircuitBreaker/decorateCallable breaker f))
;; retry
(defmacro execute-with-retry [^Retry retry & body]
`(.executeCallable ~retry ^Callable (fn [] (do ~@body))))
(defn with-retry [^Retry r f]
(Retry/decorateCallable r f))
;; bulkhead
(defmacro execute-with-bulkhead [^Bulkhead bulkhead & body]
`(.executeCallable ~bulkhead ^Callable (fn [] (do ~@body))))
(defn with-bulkhead [^Bulkhead r f]
(Bulkhead/decorateCallable r f))
;; rate limiter
(defmacro execute-with-rate-limiter [^RateLimiter ratelimiter & body]
`(.executeCallable ~ratelimiter ^Callable (fn [] (do ~@body))))
(defn with-rate-limiter [^RateLimiter r f]
(RateLimiter/decorateCallable r f))
;; time limiter
(defmacro execute-with-time-limiter [^TimeLimiter timelimiter & body]
`(.executeFutureSupplier ~timelimiter (reify Supplier
(get [_] (do ~@body)))))
(defn with-time-limiter [^TimeLimiter r f]
(TimeLimiter/decorateFutureSupplier r
(reify Supplier
(get [_] (f)))))
;; gather together
(defmacro execute* [f]
(let [f (vary-meta f assoc :tag `Callable)]
`(.call ^Callable ~f)))
(defmacro execute
[execute-body & args]
`(->> (fn [] ~execute-body)
~@args
execute*))
(defmacro to-fn [& body]
`(fn [] (do ~@body)))
(defmacro with-resilience-family [family-members & body]
(let [wrappers (map #(let [[k v] %]
(list (symbol (str "game-lobby.resilience.core/with-" (name k))) v))
(partition-all 2 family-members))]
`(->> (to-fn ~@body)
~@wrappers
execute*)))
(defn- recover-from* [exception failover-fn wraped-fn]
(let [wraped-fn (vary-meta wraped-fn assoc :tag `Callable)]
`(fn []
(try
(.call ~wraped-fn)
(catch ~exception ex#
(~failover-fn ex#))))))
(defmacro recover-from [exception failover-fn wraped-fn]
(recover-from* exception failover-fn wraped-fn))
(defmacro recover [failover-fn wraped-fn]
(recover-from* 'Exception failover-fn wraped-fn))