sparkledriver.retry
*retry-fn*
dynamic
retry-backoff
(retry-backoff max-wait try-fn)
(retry-backoff max-wait recover-fn try-fn)
Execute try-fn
, catching any exception and then retrying with an exponential backoff until a retry pause of max-wait
seconds is reached. If recover-fn
is supplied, it will be called before each retry with the most recent exception as its only argument. Either returns the result of a successful invocation of try-fn
or raises an exception.
If try-fn throws an :unhandled-fatal
exception the retry loop will terminate.
Simple example:
(retry-backoff
;; retry at 2,4 and 8 seconds
8
;; return the value of element w/ id "the-id" if successful
#(find-by-id browser "the-id"))
Add a recovery-fn
to the retry, which in this case just logs the exception:
(retry-backoff
;; retry at 2,4,8 and 16 seconds
16
;; "recover-fn" that logs failures between retries
#(info (str "Trying again after a " (.getMessage %) " exception..."))
;; return the value of element w/ id "the-id" if successful
#(find-by-id browser "the-id"))
with-retry
macro
(with-retry retry-fn & body)
Evaluate body
with retry-fn
bound to the dynamic variable *retry-fn*
. Many Sparkledriver functions automatically wrap themselves in *retry-fn*
when it is bound, which allows one to specify a retry policy for those functions within the scope of this macro.
Example:
(with-browser [browser (make-browser)]
(fetch! browser "http://clojure.org")
(with-retry (partial retry-backoff 16)
(-> browser
(find-by-xpath* "//div[@class='clj-intro-message']/p")
(nth 2)
text)))
;;=> "I hope you find Clojure's combination of facilities elegant, powerful, practical and fun to use."