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

feat(shared): Replace callWithRetry and runWithExponentialBackoff with retry #5144

Open
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

nikosdouvlis
Copy link
Member

@nikosdouvlis nikosdouvlis commented Feb 13, 2025

Description

  • Replace callWithRetry with runWithExponentialBackOff so we only have a single retry mechanism in use
  • Rename runWithExponentialBackOff to retry for clarity
  • Add the following config options to runWithExponentialBackOff :
    • retryImmediately (boolean): Controls whether the helper should retry the operation immediately. If true, the exponential backoff delay will start only once this retry is over. Defaults to true.
    • jitter (boolean): If true, the intervals will be multiplied by a factor of [1,2]. Defaults to true.
  • Increase unit test coverage (retry.test.ts)

Checklist

  • pnpm test runs as expected.
  • pnpm build runs as expected.
  • (If applicable) JSDoc comments have been added or updated for any package exports
  • (If applicable) Documentation has been updated

Type of change

  • 🐛 Bug fix
  • 🌟 New feature
  • 🔨 Breaking change
  • 📖 Refactoring / dependency upgrade / documentation
  • other:

Copy link

changeset-bot bot commented Feb 13, 2025

🦋 Changeset detected

Latest commit: c48f5d3

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 20 packages
Name Type
@clerk/shared Major
@clerk/agent-toolkit Patch
@clerk/astro Patch
@clerk/backend Patch
@clerk/chrome-extension Patch
@clerk/clerk-js Patch
@clerk/elements Patch
@clerk/expo-passkeys Patch
@clerk/clerk-expo Patch
@clerk/express Patch
@clerk/fastify Patch
@clerk/nextjs Patch
@clerk/nuxt Patch
@clerk/react-router Patch
@clerk/clerk-react Patch
@clerk/remix Patch
@clerk/tanstack-start Patch
@clerk/testing Patch
@clerk/ui Patch
@clerk/vue Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

Copy link

vercel bot commented Feb 13, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
clerk-js-sandbox 🛑 Canceled (Inspect) Feb 14, 2025 0:51am

@nikosdouvlis
Copy link
Member Author

!allow-major

packages/shared/src/retry.ts Outdated Show resolved Hide resolved
packages/shared/src/retry.ts Outdated Show resolved Hide resolved
packages/shared/src/retry.ts Show resolved Hide resolved
Comment on lines 32 to 37
retryImmediatelyOnce: boolean;
/**
* The delay for the immediate retry.
* @default 100
*/
retryImmediatelyDelay: Milliseconds;
Copy link
Member

Choose a reason for hiding this comment

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

These two options feel weird, I can't put a finger on it but this seems like something that should be only one option and be renamed.

  • Retrying immediately already implies that it can only happen once, right? Afterwards it's not immediate anymore
  • Technically "immediate" would be a delay of 0 so the current default of 100 is already quite arbitrary. Why should we need to change this from a case by case basis?

So I'd just put those two options into one called retryImmediate: boolean

Copy link
Member Author

Choose a reason for hiding this comment

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

Tagging @panteliselef as he was also interested about this - Im also open to suggestions to improve this further.
There are at least two cases where we might want to immediately retry, before applying the backoff strategy:

  • mission-critical operations that need to be completed as fast as possible
  • transient errors on the network level (think about mobile devices)

This property decouples the immediate retry with the rest of the backoff logic, as its very hard to tune the options using a combination of factor + initialDelay otherwise.

Copy link
Member Author

@nikosdouvlis nikosdouvlis Feb 14, 2025

Choose a reason for hiding this comment

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

I'm going to merge these two into a single retryImmediately: boolean with a default delay of 100ms. If we ever need to change this, we can add a new prop then

Copy link
Member Author

Choose a reason for hiding this comment

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

Done

packages/shared/src/retry.ts Show resolved Hide resolved
packages/shared/src/retry.ts Show resolved Hide resolved
packages/shared/src/__tests__/retry.test.ts Outdated Show resolved Hide resolved
packages/shared/src/__tests__/retry.test.ts Outdated Show resolved Hide resolved
packages/shared/src/__tests__/retry.test.ts Outdated Show resolved Hide resolved
nikosdouvlis and others added 3 commits February 14, 2025 14:47
Co-authored-by: Lennart <lekoarts@gmail.com>
Co-authored-by: Lennart <lekoarts@gmail.com>
Co-authored-by: Lennart <lekoarts@gmail.com>
@@ -137,8 +137,8 @@ export async function loadClerkJWKFromRemote({
reason: TokenVerificationErrorReason.RemoteJWKFailedToLoad,
});
}
const fetcher = () => fetchJWKSFromBAPI(apiUrl, secretKey, apiVersion);
const { keys } = await callWithRetry<{ keys: JsonWebKeyWithKid[] }>(fetcher);
const fetcher = () => fetchJWKSFromBAPI(apiUrl, secretKey, apiVersion) as Promise<{ keys: JsonWebKeyWithKid[] }>;
Copy link
Member

Choose a reason for hiding this comment

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

❓ why do we need to cast here?

Copy link
Member

@brkalow brkalow left a comment

Choose a reason for hiding this comment

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

👏

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants