-
Notifications
You must be signed in to change notification settings - Fork 411
feat(clerk-js): Stale-while-revalidate session token #7317
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
base: vincent-and-the-doctor
Are you sure you want to change the base?
feat(clerk-js): Stale-while-revalidate session token #7317
Conversation
|
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the You can disable this status message by setting the ✨ Finishing touches🧪 Generate unit tests (beta)
Comment |
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
| const tokenResolver = Token.create(path, params, false); | ||
|
|
||
| // Cache the promise immediately to prevent concurrent calls from triggering duplicate requests | ||
| SessionTokenCache.set({ tokenId, tokenResolver }); |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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
@clerk/agent-toolkit
@clerk/astro
@clerk/backend
@clerk/chrome-extension
@clerk/clerk-js
@clerk/dev-cli
@clerk/expo
@clerk/expo-passkeys
@clerk/express
@clerk/fastify
@clerk/localizations
@clerk/nextjs
@clerk/nuxt
@clerk/react
@clerk/react-router
@clerk/shared
@clerk/tanstack-react-start
@clerk/testing
@clerk/ui
@clerk/upgrade
@clerk/vue
commit: |
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 testruns as expected.pnpm buildruns as expected.Type of change