segmentio / analytics-node

The hassle-free way to integrate analytics into any node application.

Home Page:https://segment.com/libraries/node

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Add jitter to retry timeout

Dahaden opened this issue · comments

We would love to be able to add jitter to the retry logic in order to prevent retry storms from the hosts impacted by an outage.

This is something that axiosRetry can support through a custom function but I am wondering what the preferred approach to this is.

The options I see are:

  1. Add an option for jitter like in the @segment/localstorage-retry library,
  2. Add an option for the axiosRetryConfig which we can merge with the defaults and pass into axiosRetry, or
  3. Add an option for axiosRetryInstance like axiosInstance.

My only concern with 3 is that axiosInstance need to be passed into axiosRetry and this may be easy to miss-configure if someone is playing around with this.

Actually I might even go with option 1 (Add option for jitter) as then users cant mistakenly overwrite the retryCondition option

Sorry just noticed that axios retry does add 20% jitter to their delays via exponentialDelay https://github.com/softonic/axios-retry/blob/master/es/index.js#L77-L81

I know it sounds counter intuitive, but I am wondering if this should be random_between(0, exponentialDelay) to give a greater variance for the jitter.
https://aws.amazon.com/blogs/architecture/exponential-backoff-and-jitter/

How would users mistakenly override the retryCondition option?

I like option 2 better but at the same time it leaves things too open. Maybe create an "allowance list" of the parameters that can be passed into retryConfig? Maybe that's why you're saying users can mistakenly overwrite things.

Something to keep in mind is that you can pass your own axiosInstance to the constructor. The only issue is that it'll "apply" axiosRetry again. And axiosRetry adds request/response interceptors so I'm thinking that wouldn't look nice. But we can always check if retryCount is 0, and if it is completely skip axiosRetry. Which is essentially the option #3(?)

Yea possibly being a bit naive there, but mainly thinking if someone replaces the retryCondition thinking that they needed to?

An allowance list sounds like a great idea though!

Huh yea didnt think of wrapping the axiosInstance prior to passing it in either. Checking retryCount === 0 is a great idea, will chuck this in a PR.

Thanks!