Skip to content

Commit

Permalink
perf(scheduler-utils): add exponential backoff to gateway requests
Browse files Browse the repository at this point in the history
  • Loading branch information
jfrain99 committed Jul 30, 2024
1 parent e6981b3 commit e3e2049
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 6 deletions.
16 changes: 10 additions & 6 deletions scheduler-utils/src/client/gateway.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { defaultTo, find, juxt, path, pipe, prop, propEq } from 'ramda'

import { InvalidSchedulerLocationError, SchedulerTagNotFoundError, TransactionNotFoundError } from '../err.js'
import { backoff, okRes } from '../utils.js'

const URL_TAG = 'Url'
const TTL_TAG = 'Time-To-Live'
Expand All @@ -24,12 +25,15 @@ const findTransactionTags = (err) => pipe(

function gatewayWith ({ fetch, GRAPHQL_URL }) {
return async ({ query, variables }) => {
return fetch(GRAPHQL_URL, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ query, variables })
})
.then((res) => res.json())
return backoff(
() => fetch(GRAPHQL_URL, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ query, variables })
})
.then(okRes)
.then((res) => res.json()),
{ maxRetries: 2, delay: 300 })
}
}

Expand Down
53 changes: 53 additions & 0 deletions scheduler-utils/src/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,56 @@ export function trimSlash (str = '') {
str = str.trim()
return str.endsWith('/') ? trimSlash(str.slice(0, -1)) : str
}

/**
* A function that, given a function, will immediately invoke it,
* then retry it on errors, using an exponential backoff.
*
* If the final retry fails, then the overall Promise is rejected
* with that error
*
* @param {function} fn - the function to be called
* @param {{ maxRetries: number, delay: number }} param1 - the number of total retries and increased delay for each try
*/
export const backoff = (
fn,
{ maxRetries = 3, delay = 500 }
) => {
/**
* Recursive function that recurses with exponential backoff
*/
const action = (retry, delay) => {
return Promise.resolve()
.then(fn)
.catch((err) => {
// Reached max number of retries
if (retry >= maxRetries) {
return Promise.reject(err)
}

/**
* increment the retry count Retry with an exponential backoff
*/
const newRetry = retry + 1
const newDelay = delay + delay
/**
* Retry in {delay} milliseconds
*/
return new Promise((resolve) => setTimeout(resolve, delay))
.then(() => action(newRetry, newDelay))
})
}

return action(0, delay)
}

/**
* Checks if a response is OK. Otherwise, throw response.
*
* @param {Response} res - The response to check
* @returns
*/
export const okRes = (res) => {
if (res.ok) return res
throw res
}

0 comments on commit e3e2049

Please sign in to comment.