add better logs around worker restarts (#57004)

We currently log when a worker is restarted but not when we send the kill signal, which can create a delta in logs of cryptic errors while the worker is exiting. This explicitly logs when we're terminating the static worker prior to a restart, and also adds an optional logger fn so that we pretty-print the messages. 

[slack x-ref](https://vercel.slack.com/archives/C061DJBG8PN/p1697491350970269)
This commit is contained in:
Zack Tanner 2023-10-18 09:11:40 -07:00 committed by GitHub
parent 2c8606e596
commit c2ac8df073
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 16 additions and 4 deletions

View file

@ -1207,6 +1207,7 @@ export default async function build(
return new Worker(staticWorkerPath, {
timeout: timeout * 1000,
logger: Log,
onRestart: (method, [arg], attempts) => {
if (method === 'exportPage') {
const pagePath = arg.path

View file

@ -21,11 +21,12 @@ export class Worker {
options: FarmOptions & {
timeout?: number
onRestart?: (method: string, args: any[], attempts: number) => void
logger?: Pick<typeof console, 'error' | 'info' | 'warn'>
exposedMethods: ReadonlyArray<string>
enableWorkerThreads?: boolean
}
) {
let { timeout, onRestart, ...farmOptions } = options
let { timeout, onRestart, logger = console, ...farmOptions } = options
let restartPromise: Promise<typeof RESTARTED>
let resolveRestartPromise: (arg: typeof RESTARTED) => void
@ -68,10 +69,9 @@ export class Worker {
_child?: ChildProcess
}[]) {
worker._child?.on('exit', (code, signal) => {
// log unexpected exit if .end() wasn't called
if ((code || (signal && signal !== 'SIGINT')) && this._worker) {
console.error(
`Static worker unexpectedly exited with code: ${code} and signal: ${signal}`
logger.error(
`Static worker exited with code: ${code} and signal: ${signal}`
)
}
})
@ -88,6 +88,11 @@ export class Worker {
if (!worker) return
const resolve = resolveRestartPromise
createWorker()
logger.warn(
`Sending SIGTERM signal to static worker due to timeout${
timeout ? ` of ${timeout / 1000} seconds` : ''
}. Subsequent errors may be a result of the worker exiting.`
)
worker.end().then(() => {
resolve(RESTARTED)
})

View file

@ -8,6 +8,12 @@ describe('worker-restart', () => {
})
const output = stdout + stderr
expect(output).toContain(
'Sending SIGTERM signal to static worker due to timeout of 10 seconds. Subsequent errors may be a result of the worker exiting.'
)
expect(output).toContain(
'Static worker exited with code: null and signal: SIGTERM'
)
expect(output).toContain(
'Restarted static page generation for /bad-page because it took more than 10 seconds'
)