Fork me on GitHub
#re-frame
<
2021-08-16
>
Michael Stokley00:08:00

i'm looking at retrying api calls, but i'd like to have the retries exponentially back off

Michael Stokley00:08:22

what's the best way to dispatch an event after a pause?

Michael Stokley01:08:53

seems like js/setTimeout would most work for side effecting functions. but in the context of re-frame, i think the functions are pure...

Michael Stokley02:08:19

> seems like `js/setTimeout` would most work for side effecting functions. but in the context of re-frame, i think the functions are pure... then again, an api call is a side effect. so maybe js/setTimeout would be fairly straightforward here.

Michael Stokley02:08:49

we have an api call effect handler, i can just write another that accepts a delay and invoke setTimeout

emccue02:08:47

yep, so what I would do is

(rf/reg-fx
  ::delayed-dispatch
  (fn [{:keys [event delay]}]
    (js/setTimeout #(rf/dispatch event) delay)))

(defn delayed-dispatch
  [{:keys [event delay] :as args}]
  [[::delayed-dispatch args]])

...

(defn your-http-fx
  [args]
  [[::http-effect args]]

...

(rf/reg-event-fx
  ::failed-call
  (fn [...]
    {:fx (delayed-dispatch [::make-call ...] ... delay ...)}))

(rf/reg-event-fx
  ::make-call
  (fn [{:keys [db]} [_ delay]]
    {:fx (your-http-fx ... :on-failure ::failed-call)}))

emccue02:08:55

obviously very pseudocode

emccue02:08:27

but this is a perfectly acceptable use of fx - waiting for a delay is something that can be considered an "outside subsystem"

emccue02:08:27

just store the number of requests so far, current delay, whatever either in the app db or implicitly in the looping chain