Skip to content

feat(jobs): handle SIGTERM in job runner for graceful shutdown from Docker/systemd #1612

@lisa-assistant

Description

@lisa-assistant

Background

In packages/jobs/src/bins/rw-jobs.ts, the signalSetup function (line 187) only sets up a handler for SIGINT (Ctrl+C):

process.on('SIGINT', () => {
  // forwards SIGINT to each worker for graceful shutdown
  workers.forEach(worker => worker.kill('SIGINT'))
})

There is a TODO at line 150 noting that SIGTERM/SIGKILL support is missing:

// TODO add support for stopping with SIGTERM or SIGKILL?
export const stopWorkers = async ({ ... signal = 'SIGINT', ... }) => { ... }

SIGTERM is the standard signal sent by Docker, Kubernetes, and systemd when stopping a container or service. Without a SIGTERM handler in the parent process, the job runner ignores graceful shutdown requests from container orchestration — workers may be hard-killed without finishing their current job.

What needs to be done

Add a SIGTERM handler in signalSetup that forwards graceful shutdown to workers, mirroring the SIGINT behavior:

// SIGTERM: sent by Docker, systemd, Kubernetes during shutdown
process.on('SIGTERM', () => {
  logger.info('SIGTERM received: shutting down workers gracefully...')
  workers.forEach((worker) => {
    worker.kill('SIGTERM')
  })
})

This ensures that when the container/service is stopped, in-progress jobs get a chance to complete or be re-queued rather than being abruptly killed.

Additional consideration

The stop command in main() currently always uses SIGINT:

case 'stop':
  return await stopWorkers({ numWorkers, signal: 'SIGINT', logger })

Consider adding a --signal flag to the CLI so operators can choose SIGTERM for deployment scenarios.

File

packages/jobs/src/bins/rw-jobs.ts, lines 150 and 187–220

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions