Skip to content

Commit

Permalink
ensure webpack worker exits bubble to parent process (#72921)
Browse files Browse the repository at this point in the history
This matches the handling added in #70997 but for the Webpack build
worker. This unifies the worker code to be the same as the one for the
static export worker which already handles this case.

When the worker exits ungracefully, we need to propagate an error signal
to the parent process so that it doesn't hang.

Fixes #67097
Closes NDX-485
Closes #67154
  • Loading branch information
ztanner authored Nov 18, 2024
1 parent dacf6d8 commit df2c4a3
Showing 1 changed file with 14 additions and 34 deletions.
48 changes: 14 additions & 34 deletions packages/next/src/build/webpack-build/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@ import type { COMPILER_INDEXES } from '../../shared/lib/constants'
import * as Log from '../output/log'
import { NextBuildContext } from '../build-context'
import type { BuildTraceContext } from '../webpack/plugins/next-trace-entrypoints-plugin'
import { Worker } from 'next/dist/compiled/jest-worker'
import { Worker } from '../../lib/worker'
import origDebug from 'next/dist/compiled/debug'
import type { ChildProcess } from 'child_process'
import path from 'path'
import { exportTraceState, recordTraceEvents } from '../../trace'

Expand Down Expand Up @@ -38,44 +37,24 @@ async function webpackBuildWithWorker(

prunedBuildContext.pluginState = pluginState

const getWorker = (compilerName: string) => {
const _worker = new Worker(path.join(__dirname, 'impl.js'), {
exposedMethods: ['workerMain'],
numWorkers: 1,
maxRetries: 0,
forkOptions: {
env: {
...process.env,
NEXT_PRIVATE_BUILD_WORKER: '1',
},
const worker = new Worker(path.join(__dirname, 'impl.js'), {
exposedMethods: ['workerMain'],
numWorkers: 1,
maxRetries: 0,
forkOptions: {
env: {
...process.env,
NEXT_PRIVATE_BUILD_WORKER: '1',
},
}) as Worker & typeof import('./impl')
_worker.getStderr().pipe(process.stderr)
_worker.getStdout().pipe(process.stdout)

for (const worker of ((_worker as any)._workerPool?._workers || []) as {
_child: ChildProcess
}[]) {
worker._child.on('exit', (code, signal) => {
if (code || (signal && signal !== 'SIGINT')) {
debug(
`Compiler ${compilerName} unexpectedly exited with code: ${code} and signal: ${signal}`
)
}
})
}

return _worker
}
},
}) as Worker & typeof import('./impl')

const combinedResult = {
duration: 0,
buildTraceContext: {} as BuildTraceContext,
}

for (const compilerName of compilerNames) {
const worker = getWorker(compilerName)

const curResult = await worker.workerMain({
buildContext: prunedBuildContext,
compilerName,
Expand All @@ -88,8 +67,6 @@ async function webpackBuildWithWorker(
if (nextBuildSpan && curResult.debugTraceEvents) {
recordTraceEvents(curResult.debugTraceEvents)
}
// destroy worker so it's not sticking around using memory
await worker.end()

// Update plugin state
pluginState = deepMerge(pluginState, curResult.pluginState)
Expand Down Expand Up @@ -125,6 +102,9 @@ async function webpackBuildWithWorker(
}
}

// destroy worker so it's not sticking around using memory
worker.end()

if (compilerNames.length === 3) {
Log.event('Compiled successfully')
}
Expand Down

0 comments on commit df2c4a3

Please sign in to comment.