Skip to content

Conversation

@jacekradko
Copy link
Member

@jacekradko jacekradko commented Nov 26, 2025

Description

Return a cached token and schedule background refresh if the token is read while in the expiration leeway timeframe.

Fixes: USER-4087

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:

@changeset-bot
Copy link

changeset-bot bot commented Nov 26, 2025

⚠️ No Changeset found

Latest commit: 1c722cf

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

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

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 26, 2025

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/stale-while-revalidate-token

Comment @coderabbitai help to get the list of available commands and usage tips.

@vercel
Copy link

vercel bot commented Nov 26, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
clerk-js-sandbox Ready Ready Preview Comment Dec 3, 2025 3:02pm

@jacekradko jacekradko marked this pull request as ready for review December 1, 2025 17:23
const tokenResolver = Token.create(path, params, false);

// Cache the promise immediately to prevent concurrent calls from triggering duplicate requests
SessionTokenCache.set({ tokenId, tokenResolver });
Copy link

Choose a reason for hiding this comment

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

This will update the tokenResolver during the background refresh. As per the separate comment, this is not a problem during this getToken call, but wont this be a problem for any subsequent getToken calls?

I haven't verified this, so it's just my reading of the code, but I saw no test cases for this which might also be nice to add.

Say I have two queries using getToken, both triggered from components that render together. The first getToken call triggers a background refresh, which sets the tokenResolver to a promise. This first getToken returns the value immediately as it awaits the previous tokenResolver.

The second call to getToken runs immediately after, does not call a background refresh since one is in progress, but it does read the value via await tokenResolver which is now the promise for the background refresh, because of this, the second getToken call does not SWR correctly even if it should?

Since we might have to touch tokenResolver etc to fix this, this might (or might not!) be a good time to tackle something related too. Awaiting already finished promises still always resolve in a microtask at the end of the JS frame, which is inefficient, so we'll want some way to read the value synchronously after the fetch has finished. Just mentioning that in case this happens to align nicely with a fix for the above.

Copy link
Member Author

Choose a reason for hiding this comment

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

Great catch. Indeed, concurrent calls while refreshing would behave incorrectly as we were awaiting the new in-flight token resolver instead of returning the stale value. To address this, we no longer cache the tokenResolver running in the background until it succeeds, unlike the normal fetch case where it's cached immediately to dedupe requests. We also added a resolvedToken value to the cache so it can be read synchronously without awaiting the resolver, which avoids the microtask overhead you mentioned.

b3f14aa

Copy link
Member Author

Choose a reason for hiding this comment

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

Also expanded the test coverage of the SWR behavior

@pkg-pr-new
Copy link

pkg-pr-new bot commented Dec 2, 2025

Open in StackBlitz

@clerk/agent-toolkit

npm i https://pkg.pr.new/@clerk/agent-toolkit@7317

@clerk/astro

npm i https://pkg.pr.new/@clerk/astro@7317

@clerk/backend

npm i https://pkg.pr.new/@clerk/backend@7317

@clerk/chrome-extension

npm i https://pkg.pr.new/@clerk/chrome-extension@7317

@clerk/clerk-js

npm i https://pkg.pr.new/@clerk/clerk-js@7317

@clerk/dev-cli

npm i https://pkg.pr.new/@clerk/dev-cli@7317

@clerk/expo

npm i https://pkg.pr.new/@clerk/expo@7317

@clerk/expo-passkeys

npm i https://pkg.pr.new/@clerk/expo-passkeys@7317

@clerk/express

npm i https://pkg.pr.new/@clerk/express@7317

@clerk/fastify

npm i https://pkg.pr.new/@clerk/fastify@7317

@clerk/localizations

npm i https://pkg.pr.new/@clerk/localizations@7317

@clerk/nextjs

npm i https://pkg.pr.new/@clerk/nextjs@7317

@clerk/nuxt

npm i https://pkg.pr.new/@clerk/nuxt@7317

@clerk/react

npm i https://pkg.pr.new/@clerk/react@7317

@clerk/react-router

npm i https://pkg.pr.new/@clerk/react-router@7317

@clerk/shared

npm i https://pkg.pr.new/@clerk/shared@7317

@clerk/tanstack-react-start

npm i https://pkg.pr.new/@clerk/tanstack-react-start@7317

@clerk/testing

npm i https://pkg.pr.new/@clerk/testing@7317

@clerk/ui

npm i https://pkg.pr.new/@clerk/ui@7317

@clerk/upgrade

npm i https://pkg.pr.new/@clerk/upgrade@7317

@clerk/vue

npm i https://pkg.pr.new/@clerk/vue@7317

commit: 1c722cf

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants