Skip to content

Commit

Permalink
Use CacheStore instead of fetchCache
Browse files Browse the repository at this point in the history
That way we don't need to shadow the outer WorkStore by cloning it so there
is only one that is safe to mutate.
  • Loading branch information
sebmarkbage committed Oct 3, 2024
1 parent b23ef31 commit 7043654
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 27 deletions.
6 changes: 5 additions & 1 deletion packages/next/src/server/lib/patch-fetch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,11 @@ export function createPatchedFetcher(
}
const implicitTags = addImplicitTags(workStore, requestStore)

const pageFetchCacheMode = workStore.fetchCache
// Inside unstable-cache we treat it the same as force-no-store on the page.
const pageFetchCacheMode =
cacheStore && cacheStore.type === 'unstable-cache'
? 'force-no-store'
: workStore.fetchCache
const isUsingNoStore = !!workStore.isUnstableNoStore

let currentFetchCacheConfig = getRequestMeta('cache')
Expand Down
38 changes: 12 additions & 26 deletions packages/next/src/server/web/spec-extension/unstable-cache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ export function unstable_cache<T extends Callback>(
const cachedCb = async (...args: any[]) => {
const workStore = workAsyncStorage.getStore()
const requestStore = requestAsyncStorage.getStore()
const cacheStore = cacheAsyncStorage.getStore()

// We must be able to find the incremental cache otherwise we throw
const maybeIncrementalCache:
Expand Down Expand Up @@ -185,9 +186,13 @@ export function unstable_cache<T extends Callback>(
// of this function is potentially a little confusing
const implicitTags = addImplicitTags(workStore, requestStore)

const isNestedCache =
cacheStore &&
(cacheStore.type === 'unstable-cache' || cacheStore.type === 'cache')
if (
// when we are nested inside of other unstable_cache's
// we should bypass cache similar to fetches
!isNestedCache &&
workStore.fetchCache !== 'force-no-store' &&
!workStore.isOnDemandRevalidate &&
!incrementalCache.isOnDemandRevalidate &&
Expand Down Expand Up @@ -227,20 +232,12 @@ export function unstable_cache<T extends Callback>(
if (!workStore.pendingRevalidates) {
workStore.pendingRevalidates = {}
}
const cacheStore: UnstableCacheStore = {
const innerCacheStore: UnstableCacheStore = {
type: 'unstable-cache',
}
// We run the cache function asynchronously and save the result when it completes
workStore.pendingRevalidates[invocationKey] = workAsyncStorage
.run(
{
...workStore,
// force any nested fetches to bypass cache so they revalidate
// when the unstable_cache call is revalidated
fetchCache: 'force-no-store',
},
() => cacheAsyncStorage.run(cacheStore, cb, ...args)
)
workStore.pendingRevalidates[invocationKey] = cacheAsyncStorage
.run(innerCacheStore, cb, ...args)
.then((result) => {
return cacheNewResult(
result,
Expand All @@ -266,19 +263,11 @@ export function unstable_cache<T extends Callback>(
}
}

const cacheStore: UnstableCacheStore = {
const innerCacheStore: UnstableCacheStore = {
type: 'unstable-cache',
}
// If we got this far then we had an invalid cache entry and need to generate a new one
const result = await workAsyncStorage.run(
{
...workStore,
// force any nested fetches to bypass cache so they revalidate
// when the unstable_cache call is revalidated
fetchCache: 'force-no-store',
},
() => cacheAsyncStorage.run(cacheStore, cb, ...args)
)
const result = await cacheAsyncStorage.run(innerCacheStore, cb, ...args)

if (!workStore.isDraftMode) {
cacheNewResult(
Expand Down Expand Up @@ -337,7 +326,7 @@ export function unstable_cache<T extends Callback>(
}
}

const cacheStore: UnstableCacheStore = {
const innerCacheStore: UnstableCacheStore = {
type: 'unstable-cache',
}
// If we got this far then we had an invalid cache entry and need to generate a new one
Expand All @@ -352,16 +341,13 @@ export function unstable_cache<T extends Callback>(
// The fact that we need to construct this kind of fake store indicates the code is not factored correctly
// @TODO refactor to not require this fake store object
{
// force any nested fetches to bypass cache so they revalidate
// when the unstable_cache call is revalidated
fetchCache: 'force-no-store',
route: '/',
page: '/',
isStaticGeneration: false,
fallbackRouteParams: null,
buildId: '', // Since this is a fake one it can't "use cache" anyway.
},
() => cacheAsyncStorage.run(cacheStore, cb, ...args)
() => cacheAsyncStorage.run(innerCacheStore, cb, ...args)
)
cacheNewResult(
result,
Expand Down

0 comments on commit 7043654

Please sign in to comment.