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

Add exponential backoff to request retries #101

Merged
merged 5 commits into from
Jun 6, 2024
Merged

Add exponential backoff to request retries #101

merged 5 commits into from
Jun 6, 2024

Conversation

JoshMock
Copy link
Member

@JoshMock JoshMock commented Jun 5, 2024

Uses an exponential backoff algorithm that includes some jitter so that retries are not going to hammer several sequential requests at an Elasticsearch instance that might be failing or trying to catch up. Some random jitter is added to the backoff to ensure a more smooth distribution of retries.

A retryBackoff option is exposed on both the transport constructor and request function, but I'm not planning to document it. Exposing it is primarily to make unit testing easier. (Who would have guessed that testing code that uses time and random numbers would be frustrating?) That said, more advanced users might see value in providing their own backoff algorithm to meet their particular needs.

@JoshMock
Copy link
Member Author

JoshMock commented Jun 5, 2024

Pinging all my dynamic language friends for a review, mostly because it's interesting. 🙂


// exponential backoff on retries, with jitter
const backoff = options.retryBackoff ?? this[kRetryBackoff]
const backoffWait = backoff(0, 4, meta.attempts)
Copy link

@miguelgrinberg miguelgrinberg Jun 6, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems like your intention is not to expose this as a feature to developers, so maybe this isn't important right now, but would it make sense to future-proof this and make the min and max arguments also configurable, like the attempts are?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good question. Nobody in the community asked for retry backoff, much less the ability to provide their own algorithm, so I think we can wait until someone actually asks for it?

miguelgrinberg
miguelgrinberg previously approved these changes Jun 6, 2024
src/Transport.ts Outdated
*/
function retryBackoff (min: number, max: number, attempt: number): number {
const ceiling = Math.min(max, 2 ** attempt) / 2
return ceiling + ((Math.random() * (ceiling - min)) - min)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The expression ((Math.random() * (ceiling - min)) - min) generates a random number between -min and ceiling - 2 * min. Was this what you intended here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice catch. 😆 Fixed in 003353e.

Accidentally let the minimum be `min * -1` instead of `min`. Whoops!
@JoshMock
Copy link
Member Author

JoshMock commented Jun 6, 2024

Merging mostly so I can get this in before publishing the 8.14 client. We can continue to iterate on the implementation based on how this works, especially once Elastic Cloud SREs start to see a difference in retry handling from Kibana.

@JoshMock JoshMock merged commit 8fed57b into main Jun 6, 2024
12 checks passed
@JoshMock JoshMock deleted the retry-backoff branch June 6, 2024 17:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants