-
Notifications
You must be signed in to change notification settings - Fork 87
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: make CDN SWR background revalidation discard stale cache content in order to produce fresh responses #2765
Conversation
📊 Package size report 0.03%↑
Unchanged files
🤖 This report was automatically generated by pkg-size-action |
3ab37f8
to
aca7cdd
Compare
…t in order to produce fresh responses
aca7cdd
to
0a28ab9
Compare
…ng background SWR requests
d630cb3
to
87fe9b4
Compare
expect(date1.localeCompare(beforeFirstFetch)).toBeGreaterThan(0) | ||
|
||
// allow page to get stale | ||
await page.waitForTimeout(60_000) |
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.
:( need for Durable so reduce potential flakiness if different edge nodes would be used - tested page has 60s revalidate time because of that as well
|
||
export const config: Config = { | ||
path: '/api/purge-cdn', | ||
} |
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.
I had some troubles with this function being in Next.js api handler - in the end I don't rely on it for added test, but overall it doesn't really make sense to use Next.js API for it, if it can use just vanilla Netlify function, as it only purge cdn cache, and not any Next.js caches in blobs
blob.value?.kind === 'PAGE' || | ||
blob.value?.kind === 'PAGES' || | ||
blob.value?.kind === 'APP_PAGE' | ||
) { |
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.
Is this list exhaustive?
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 is all kind
s that we do support (and not hit this case
opennextjs-netlify/src/run/handlers/cache.cts
Lines 285 to 286 in f3e24b1
default: | |
span.recordException(new Error(`Unknown cache entry kind: ${blob.value?.kind}`)) |
But right now this is manually constructed and there is no guard rail ensuring this list gets updated and in sync in the future.
Will think about best way of ensuring that all supported kind
s are in here (but I would do this probably as follow up in case I don't figure out quick/easy solution)
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.
Ok, there is a way but it's rather not pretty - full tsc
check results in pretty awful errors then that are really non-descript (if we miss kind) and the whole setup looks pretty iffy, so I would rather not go this road.
https://typescript-eslint.io/rules/switch-exhaustiveness-check/ would be great for this ... but it doesn't really work with version of eslint-typescript we have - we would need some major upgrades of this ... which would require major upgrades of bunch of other things. Those major upgrades also change default configs.
And lastly - we don't even control those versions ourselves - and shared config we use was last released ... over 2 years ago ( https://github.com/netlify/eslint-config-node/releases )
So, I won't be touching this in this PR and will keep it as is
5f084d4
to
45f3a0a
Compare
Description
We are currently having "double SWR":
This leads to us having to instruct edge not to cache stale responses served by Next serverless handler as otherwise it would lead to stale content lingering for longer than it should.
This is making use of new request headers and for background SWR revalidation invocation - we instruct cache handler to discard stale entries. Do note - that it might result in discarding
APP_PAGE
entry when it's stale, but not necessarily discardingFETCH
entry (if it's not stale) - this is behavior we see on Vercel and it is intentional.Documentation
Tests
Initially testing was done manually for various scenarios comparing those changes both against the way things work today and when deployed on Vercel - from those manual tests things seem to be working correctly:
a) served content remain the same as with current setup (just it leads to less invocations and ability to serve content directly from edge caches without blocking on serverless responses)
b) comparing against behavior when deployed on Vercel and reported status (
x-vercel-cache
)For our automated tests - added test case that should ensure that responses (minus very first one) are from edge or durable caches and that responses have expected content which should prove that background revalidation requests results in producing fresh responses that can be cached on the edge/in durable
Relevant links (GitHub issues, etc.) or a picture of cute animal
resolves https://linear.app/netlify/issue/FRB-1639/investigate-disabling-double-swr-behavior-in-next-runtime