Skip to content

Commit

Permalink
Remove revalidate property from incremental cache ctx for FETCH
Browse files Browse the repository at this point in the history
The `revalidate` property of the `ctx` object that is passed into the
incremental cache by the patched `fetch` as well as `unstable_cache`
is unused since it was introduced in #43659. It was just added because
of how the method signature for `set()` was changed back then.

However, for those kinds of cache entries, the `revalidate` context
property is never used, and instead the `revalidate` property of the
passed-in `data` is used.

To avoid further confusion (e.g. in [this
question](#76207 (comment))),
this PR improves the method signatures and types of the incremental
cache so that the different call-site use cases can be clearly
discriminated, and superfluous context properties can be omitted.
  • Loading branch information
unstubbable committed Feb 25, 2025
1 parent 6a5d676 commit 61b8a92
Show file tree
Hide file tree
Showing 13 changed files with 218 additions and 185 deletions.
4 changes: 3 additions & 1 deletion packages/next/errors.json
Original file line number Diff line number Diff line change
Expand Up @@ -649,5 +649,7 @@
"648": "@rspack/plugin-react-refresh is not available. Please make sure `@next/plugin-rspack` is correctly installed.",
"649": "Cache handlers not initialized",
"650": "experimental.nodeMiddleware",
"651": "Unexpected module type %s"
"651": "Unexpected module type %s",
"652": "Expected cached value for cache key %s not to be a %s kind, got \"FETCH\" instead.",
"653": "Expected cached value for cache key %s to be a \"FETCH\" kind, got %s instead."
}
12 changes: 6 additions & 6 deletions packages/next/src/server/image-optimizer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ import {
CachedRouteKind,
type CachedImageValue,
type IncrementalCacheEntry,
type IncrementalCacheItem,
type IncrementalCacheValue,
type IncrementalResponseCacheEntry,
} from './response-cache'
import { sendEtagResponse } from './send-payload'
import { getContentType, getExtension } from './serve-static'
Expand Down Expand Up @@ -390,7 +390,7 @@ export class ImageOptimizerCache {
this.nextConfig = nextConfig
}

async get(cacheKey: string): Promise<IncrementalCacheEntry | null> {
async get(cacheKey: string): Promise<IncrementalResponseCacheEntry | null> {
try {
const cacheDir = join(this.cacheDir, cacheKey)
const files = await promises.readdir(cacheDir)
Expand All @@ -414,7 +414,7 @@ export class ImageOptimizerCache {
revalidateAfter:
Math.max(maxAge, this.nextConfig.images.minimumCacheTTL) * 1000 +
Date.now(),
curRevalidate: maxAge,
revalidate: maxAge,
isStale: now > expireAt,
isFallback: false,
}
Expand Down Expand Up @@ -508,7 +508,7 @@ export function getMaxAge(str: string | null | undefined): number {
}
export function getPreviouslyCachedImageOrNull(
upstreamImage: ImageUpstream,
previousCacheEntry: IncrementalCacheItem | undefined
previousCacheEntry: IncrementalCacheEntry | null | undefined
): CachedImageValue | null {
if (
previousCacheEntry?.value?.kind === 'IMAGE' &&
Expand Down Expand Up @@ -678,7 +678,7 @@ export async function imageOptimizer(
opts: {
isDev?: boolean
silent?: boolean
previousCacheEntry?: IncrementalCacheItem
previousCacheEntry?: IncrementalResponseCacheEntry | null
}
): Promise<{
buffer: Buffer
Expand Down Expand Up @@ -772,7 +772,7 @@ export async function imageOptimizer(
return {
buffer: previouslyCachedImage.buffer,
contentType,
maxAge: opts?.previousCacheEntry?.curRevalidate || maxAge,
maxAge: opts?.previousCacheEntry?.revalidate || maxAge,
etag: previouslyCachedImage.etag,
upstreamEtag: previouslyCachedImage.upstreamEtag,
}
Expand Down
40 changes: 28 additions & 12 deletions packages/next/src/server/lib/incremental-cache/file-system-cache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ import {
CachedRouteKind,
IncrementalCacheKind,
type CachedFetchValue,
type IncrementalCacheValue,
type SetIncrementalFetchCacheContext,
type SetIncrementalResponseCacheContext,
} from '../../response-cache'

import { LRUCache } from '../lru-cache'
Expand Down Expand Up @@ -106,12 +109,16 @@ export default class FileSystemCache implements CacheHandler {

public async get(...args: Parameters<CacheHandler['get']>) {
const [key, ctx] = args
const { tags, softTags, kind, isRoutePPREnabled, isFallback } = ctx
const { kind } = ctx

let data = memoryCache?.get(key)

if (this.debug) {
console.log('get', key, tags, kind, !!data)
if (kind === IncrementalCacheKind.FETCH) {
console.log('get', key, ctx.tags, kind, !!data)
} else {
console.log('get', key, kind, !!data)
}
}

// let's check the disk for seed data
Expand Down Expand Up @@ -157,6 +164,8 @@ export default class FileSystemCache implements CacheHandler {
const { mtime } = await this.fs.stat(filePath)

if (kind === IncrementalCacheKind.FETCH) {
const { tags, fetchIdx, fetchUrl } = ctx

if (!this.flushToDisk) return null

const lastModified = mtime.getTime()
Expand All @@ -177,8 +186,10 @@ export default class FileSystemCache implements CacheHandler {
console.log('tags vs storedTags mismatch', tags, storedTags)
}
await this.set(key, data.value, {
fetchCache: true,
tags,
isRoutePPREnabled,
fetchIdx,
fetchUrl,
})
}
}
Expand Down Expand Up @@ -226,10 +237,10 @@ export default class FileSystemCache implements CacheHandler {
}

let rscData: Buffer | undefined
if (!isFallback) {
if (!ctx.isFallback) {
rscData = await this.fs.readFile(
this.getFilePath(
`${key}${isRoutePPREnabled ? RSC_PREFETCH_SUFFIX : RSC_SUFFIX}`,
`${key}${ctx.isRoutePPREnabled ? RSC_PREFETCH_SUFFIX : RSC_SUFFIX}`,
IncrementalCacheKind.APP_PAGE
)
)
Expand All @@ -251,7 +262,7 @@ export default class FileSystemCache implements CacheHandler {
let meta: RouteMetadata | undefined
let pageData: string | object = {}

if (!isFallback) {
if (!ctx.isFallback) {
pageData = JSON.parse(
await this.fs.readFile(
this.getFilePath(
Expand Down Expand Up @@ -315,7 +326,10 @@ export default class FileSystemCache implements CacheHandler {
}
}
} else if (data?.value?.kind === CachedRouteKind.FETCH) {
const combinedTags = [...(tags || []), ...(softTags || [])]
const combinedTags =
ctx.kind === IncrementalCacheKind.FETCH
? [...(ctx.tags || []), ...(ctx.softTags || [])]
: []

const wasRevalidated = combinedTags.some((tag) => {
if (this.revalidatedTags.includes(tag)) {
Expand All @@ -338,9 +352,11 @@ export default class FileSystemCache implements CacheHandler {
return data ?? null
}

public async set(...args: Parameters<CacheHandler['set']>) {
const [key, data, ctx] = args
const { isFallback } = ctx
public async set(
key: string,
data: IncrementalCacheValue | null,
ctx: SetIncrementalFetchCacheContext | SetIncrementalResponseCacheContext
) {
memoryCache?.set(key, {
value: data,
lastModified: Date.now(),
Expand Down Expand Up @@ -388,7 +404,7 @@ export default class FileSystemCache implements CacheHandler {
writer.append(htmlPath, data.html)

// Fallbacks don't generate a data file.
if (!isFallback) {
if (!ctx.fetchCache && !ctx.isFallback) {
writer.append(
this.getFilePath(
`${key}${
Expand Down Expand Up @@ -441,7 +457,7 @@ export default class FileSystemCache implements CacheHandler {
filePath,
JSON.stringify({
...data,
tags: ctx.tags,
tags: ctx.fetchCache ? ctx.tags : [],
})
)
}
Expand Down
Loading

0 comments on commit 61b8a92

Please sign in to comment.