sunng87 / diehard

Clojure resilience library for flexible retry, circuit breaker and rate limiter
Eclipse Public License 2.0
330 stars 27 forks source link

Cannot use listeners with predefined policy #41

Closed jvtrigueros closed 3 years ago

jvtrigueros commented 3 years ago

I'm reading the cljdoc on predefined listeners, the documentation states:

(require '[diehard.core :as diehard])

;; added for clarity
(diehard/defretrypolicy policy
  {:max-retries 5})

(diehard/deflistener listener
  {:on-retry (fn [return-value exception-thrown] (println "retried"))})

(diehard/with-retry {:policy policy :listener listener}
  ;; your code here
  )

So problem number one here diehard/deflistener no longer exists, I see that it was introduced in version 0.3.0, but I don't know when it went away. That's fine, so we can rewrite the above code as follows:

(require '[diehard.core :as diehard])

;; added for clarity
(diehard/defretrypolicy policy
  {:max-retries 5})

(diehard/with-retry {:policy policy
                     :on-retry (fn [return-value exception-thrown] (println "retried"))}
  ;; your code here
  )

The problem here is that once the policy key is provided, all the other keys are ignored and they wont affect the provided RetryPolicy object.

My goal was to create a base RetryPolicy object once, and provide the listener functions at the call site so that I can use the inputs, something like this:

(require '[diehard.core :as diehard])

;; added for clarity
(diehard/defretrypolicy policy
  {:max-retries 5})

(defn get-user
  [id]
  (diehard/with-retry {:policy policy
                       :on-retry (fn [_ _] (println "(Re)Attempting to fetch user: " id)}
    (get-user* id))

This is a contrived example but essentially split the policy from the listeners that need local information.

TL;DR: The documentation doesn't match what the code is doing, what is the correct the code or the docs?


What I'll end up doing is define my policy as a Clojure map and assoc the listener keys at the call site, e.g.:

(require '[diehard.core :as diehard])

;; added for clarity
(def policy
  {:max-retries 5})

(defn get-user
  [id]
  (diehard/with-retry (assoc policy
                       :on-retry (fn [_ _] (println "(Re)Attempting to fetch user: " id))
    (get-user* id))
sunng87 commented 3 years ago

@jvtrigueros thank you for reporting. deflistener was removed with failsafe 2.0 iirc. I have updated to doc and will create a release to fix it on cljdoc.

{:policy policy
 :on-retry (fn [_ _] (println "(Re)Attempting to fetch user: " id)}

This case wasn't considered before but I agree it should be supported. A fix will be added soon.

sunng87 commented 3 years ago

Released in 0.10.1