Skip to content

Commit 5da8ad7

Browse files
authored
move static worker IPC server behind experimental flag (#57943)
A shared incremental cache IPC server was introduced for build-time static workers as an optimization to dedupe fetch requests, however this can cause fetch-related flakiness to builds under certain conditions (e.g., large payloads). This moves the optimization behind an experimental flag to unblock those running into IPC-related build time errors while we work on an alternative solution for the underlying issue Fixes #53695
1 parent ad55d78 commit 5da8ad7

File tree

4 files changed

+53
-37
lines changed

4 files changed

+53
-37
lines changed

packages/next/src/build/index.ts

Lines changed: 41 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1218,8 +1218,8 @@ export default async function build(
12181218
: config.experimental.cpus || 4
12191219

12201220
function createStaticWorker(
1221-
incrementalCacheIpcPort: number,
1222-
incrementalCacheIpcValidationKey: string
1221+
incrementalCacheIpcPort?: number,
1222+
incrementalCacheIpcValidationKey?: string
12231223
) {
12241224
let infoPrinted = false
12251225

@@ -1259,7 +1259,9 @@ export default async function build(
12591259
forkOptions: {
12601260
env: {
12611261
...process.env,
1262-
__NEXT_INCREMENTAL_CACHE_IPC_PORT: incrementalCacheIpcPort + '',
1262+
__NEXT_INCREMENTAL_CACHE_IPC_PORT: incrementalCacheIpcPort
1263+
? incrementalCacheIpcPort + ''
1264+
: undefined,
12631265
__NEXT_INCREMENTAL_CACHE_IPC_KEY:
12641266
incrementalCacheIpcValidationKey,
12651267
},
@@ -1281,42 +1283,45 @@ export default async function build(
12811283
>
12821284
}
12831285

1284-
let CacheHandler: any
1286+
let incrementalCacheIpcPort
1287+
let incrementalCacheIpcValidationKey
12851288

1286-
if (incrementalCacheHandlerPath) {
1287-
CacheHandler = require(path.isAbsolute(incrementalCacheHandlerPath)
1288-
? incrementalCacheHandlerPath
1289-
: path.join(dir, incrementalCacheHandlerPath))
1290-
CacheHandler = CacheHandler.default || CacheHandler
1291-
}
1289+
if (config.experimental.staticWorkerRequestDeduping) {
1290+
let CacheHandler
1291+
if (incrementalCacheHandlerPath) {
1292+
CacheHandler = require(path.isAbsolute(incrementalCacheHandlerPath)
1293+
? incrementalCacheHandlerPath
1294+
: path.join(dir, incrementalCacheHandlerPath))
1295+
CacheHandler = CacheHandler.default || CacheHandler
1296+
}
12921297

1293-
const {
1294-
ipcPort: incrementalCacheIpcPort,
1295-
ipcValidationKey: incrementalCacheIpcValidationKey,
1296-
} = await initializeIncrementalCache({
1297-
fs: nodeFs,
1298-
dev: false,
1299-
pagesDir: true,
1300-
appDir: true,
1301-
fetchCache: true,
1302-
flushToDisk: config.experimental.isrFlushToDisk,
1303-
serverDistDir: path.join(distDir, 'server'),
1304-
fetchCacheKeyPrefix: config.experimental.fetchCacheKeyPrefix,
1305-
maxMemoryCacheSize: config.experimental.isrMemoryCacheSize,
1306-
getPrerenderManifest: () => ({
1307-
version: -1 as any, // letting us know this doesn't conform to spec
1308-
routes: {},
1309-
dynamicRoutes: {},
1310-
notFoundRoutes: [],
1311-
preview: null as any, // `preview` is special case read in next-dev-server
1312-
}),
1313-
requestHeaders: {},
1314-
CurCacheHandler: CacheHandler,
1315-
minimalMode: ciEnvironment.hasNextSupport,
1298+
const cacheInitialization = await initializeIncrementalCache({
1299+
fs: nodeFs,
1300+
dev: false,
1301+
pagesDir: true,
1302+
appDir: true,
1303+
fetchCache: true,
1304+
flushToDisk: config.experimental.isrFlushToDisk,
1305+
serverDistDir: path.join(distDir, 'server'),
1306+
fetchCacheKeyPrefix: config.experimental.fetchCacheKeyPrefix,
1307+
maxMemoryCacheSize: config.experimental.isrMemoryCacheSize,
1308+
getPrerenderManifest: () => ({
1309+
version: -1 as any, // letting us know this doesn't conform to spec
1310+
routes: {},
1311+
dynamicRoutes: {},
1312+
notFoundRoutes: [],
1313+
preview: null as any, // `preview` is special case read in next-dev-server
1314+
}),
1315+
requestHeaders: {},
1316+
CurCacheHandler: CacheHandler,
1317+
minimalMode: ciEnvironment.hasNextSupport,
1318+
allowedRevalidateHeaderKeys:
1319+
config.experimental.allowedRevalidateHeaderKeys,
1320+
})
13161321

1317-
allowedRevalidateHeaderKeys:
1318-
config.experimental.allowedRevalidateHeaderKeys,
1319-
})
1322+
incrementalCacheIpcPort = cacheInitialization.ipcPort
1323+
incrementalCacheIpcValidationKey = cacheInitialization.ipcValidationKey
1324+
}
13201325

13211326
const pagesStaticWorkers = createStaticWorker(
13221327
incrementalCacheIpcPort,

packages/next/src/server/config-schema.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,7 @@ export const configSchema: zod.ZodType<NextConfig> = z.lazy(() =>
366366
serverMinification: z.boolean().optional(),
367367
serverSourceMaps: z.boolean().optional(),
368368
bundlePagesExternals: z.boolean().optional(),
369+
staticWorkerRequestDeduping: z.boolean().optional(),
369370
})
370371
.optional(),
371372
exportPathMap: z

packages/next/src/server/config-shared.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,10 @@ export interface ExperimentalConfig {
334334
* Enables the bundling of node_modules packages (externals) for pages server-side bundles.
335335
*/
336336
bundlePagesExternals?: boolean
337+
/**
338+
* Uses an IPC server to dedupe build-time requests to the cache handler
339+
*/
340+
staticWorkerRequestDeduping?: boolean
337341
}
338342

339343
export type ExportPathMap = {
@@ -783,6 +787,7 @@ export const defaultConfig: NextConfig = {
783787
typedRoutes: false,
784788
instrumentationHook: false,
785789
bundlePagesExternals: false,
790+
staticWorkerRequestDeduping: false,
786791
},
787792
}
788793

test/e2e/app-dir/app-fetch-deduping/app-fetch-deduping.test.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,15 @@ describe('app-fetch-deduping', () => {
3434

3535
afterAll(() => externalServer.close())
3636

37-
it('dedupes requests amongst static workers', async () => {
37+
it('dedupes requests amongst static workers when experimental.staticWorkerRequestDeduping is enabled', async () => {
3838
const next = await createNext({
3939
files: new FileRef(__dirname),
4040
env: { TEST_SERVER_PORT: `${externalServerPort}` },
41+
nextConfig: {
42+
experimental: {
43+
staticWorkerRequestDeduping: true,
44+
},
45+
},
4146
})
4247

4348
expect(requests.length).toBe(1)

0 commit comments

Comments
 (0)