Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature request: Max duration including execution time #3

Open
wontheone1 opened this issue Mar 5, 2020 · 3 comments
Open

Feature request: Max duration including execution time #3

wontheone1 opened this issue Mar 5, 2020 · 3 comments

Comments

@wontheone1
Copy link

In a use case such as:
if we want to retry calling an external service only until the caller of our service times out, etc.
It would be nice to be able to set max duration and retry interval.

@BrunoBonacci
Copy link
Owner

Hi,

I've been thinking to add such feature for a while now.
I've been a bit undecided on the clear behaviour to introduce.
I will describe here what I'm thinking so that we can see whether it matches what you are looking for.

Currently, we can put something like:

(safely
  (api-call "other-system")
  :on-error
  :max-retries 5
  :default   {:some :value})

The above code will retry the api-call for a maximum of 5 additional retries (+1 original attempt).
If after this number of retries you don't get a response, then the :default value will be returned.
The delay between retries is determined :retry-delay which by default is a randomized exponential backoff.

Similarly, we could have something like:

(safely
  (api-call "other-system")
  :on-error
  :max-retries-duration (* 2 60 1000) ;; 2mins
  :default   {:some :value})

The code above will work similarly, it will keep retrying until the :max-retries-duration budget is burned out and then return the :default value.

The :max-retries-duration could be used even in conjunction with the :max-retries whereas the call will be repeated for until either the :max-retries or :max-retries-duration expires (whichever come first).

(safely
  (api-call "other-system")
  :on-error
  :max-retries 5
  :max-retries-duration (* 2 60 1000) ;; 2mins
  :default   {:some :value})

One thing to point out is that :max-retries-duration won't guarantee that the control will be returned after approximately 2 mins (in the above examples). It just says that if the duration is passed it will give up on retries.

This is because there is no control on the execution path over the api-call which could take an arbitrary amount of time. In order to regain control after a set amount of time you need to activate the circuit breaker with :circuit-breaker :operation-name and add a :timeout (timeout only works when circuit breaker is in use).

So if you wanted to retry for at most 2min otherwise give up and regain control this is what you would need to do:

(safely
  (api-call "other-system")
  :on-error
  :max-retries-duration (* 2 60 1000) ;; 2mins
  :circuit-breaker :operation1
  :timeout (* 2 60 1000) ;; 2mins
  :default   {:some :value})

Does this make sense?

@sathyavijayan
Copy link

I think having a time bound retry mechanism would be really useful. +1 from me

@wontheone1
Copy link
Author

@BrunoBonacci Thank you for your awesome explanation. For me, what I was looking for was the time out feature along with circuit breaker. I think this feature already exist so no new feature is needed for me. I don't know if anyone wants the new :max-retries-duration option. I guess it is possible but I think for most people :timeout option makes more sense because it is more predictable since we don't have any control over how much time each trial takes.
For me, it's ok to close this issue. (Unless you want to add the new feature)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
3 participants