Skip to content

Job Context & Dependency Injection

Choose a tag to compare

@RomainLanz RomainLanz released this 01 Jan 21:20
· 74 commits to main since this release
v0.0.1-alpha.4
a1cdb72

Breaking Changes

Job Constructor Signature

The Job constructor now requires a context parameter in addition to payload:

// Before
class MyJob extends Job<Payload> {
  constructor(payload: Payload) {
    super(payload)
  }
}

// After
import type { JobContext } from '@boringnode/queue/types'

class MyJob extends Job<Payload> {
  constructor(payload: Payload, context: JobContext) {
    super(payload, context)
  }
}

Type Imports

Types must now be imported from @boringnode/queue/types:

// Before
import type { JobContext } from '@boringnode/queue'
import type { JobOptions } from '@boringnode/queue/types/main'

// After
import type { JobContext, JobOptions } from '@boringnode/queue/types'

Worker Config Rename

The pollingInterval option has been renamed to idleDelay:

// Before
worker: {
  pollingInterval: '2s'
}

// After
worker: {
  idleDelay: '2s'
}

New Features

Job Context

Jobs now have access to execution metadata via this.context:

class MyJob extends Job<Payload> {
  async execute() {
    console.log(`Job ID: ${this.context.jobId}`)
    console.log(`Attempt: ${this.context.attempt}`) // 1, 2, 3...
    console.log(`Queue: ${this.context.queue}`)
    
    if (this.context.attempt > 1) {
      console.log('This is a retry!')
    }
  }
}

Available context properties:

Property Type Description
jobId string Unique job identifier
name string Job class name
attempt number Current attempt (1-based)
queue string Queue name
priority number Job priority
acquiredAt Date When job was acquired
stalledCount number Stalled recovery count

Dependency Injection Support

Custom job instantiation via jobFactory enables IoC container integration:

await QueueManager.init({
  default: 'redis',
  adapters: { redis: redis() },
  jobFactory: async (JobClass, payload, context) => {
    return app.container.make(JobClass, [payload, context])
  }
})

Graceful Shutdown

Workers now support graceful shutdown with configurable behavior:

const worker = new Worker({
  // ...
  worker: {
    gracefulShutdown: true, // default: true
    onShutdownSignal: async () => {
      console.log('Shutdown signal received, cleaning up...')
    }
  }
})
  • gracefulShutdown - Enable/disable automatic SIGINT/SIGTERM handling (default: true)
  • onShutdownSignal - Optional callback invoked when a shutdown signal is received

Custom Logger

You can now provide a custom logger (pino-compatible interface):

import { pino } from 'pino'

await QueueManager.init({
  default: 'redis',
  adapters: { redis: redis() },
  logger: pino()
})

The logger is used for warnings (e.g., when no jobs are found for configured locations) and errors.

Named Errors Export

All error classes are now exported via the errors namespace:

import { errors } from '@boringnode/queue'

try {
  await job.dispatch()
} catch (e) {
  if (e instanceof errors.E_JOB_NOT_FOUND) {
    // handle job not found
  }
  if (e instanceof errors.E_QUEUE_NOT_INITIALIZED) {
    // QueueManager.init() was not called
  }
}

Available errors:

  • E_JOB_NOT_FOUND - Job class not registered
  • E_JOB_TIMEOUT - Job exceeded timeout
  • E_JOB_MAX_ATTEMPTS_REACHED - Job exhausted all retries
  • E_QUEUE_NOT_INITIALIZED - QueueManager not initialized
  • E_ADAPTER_INIT_ERROR - Adapter factory threw an error
  • E_CONFIGURATION_ERROR - Invalid configuration

Commits

  • refactor!: consolidate type exports under /types path (5cec963)
  • feat!: expose job context to job instances (26d8043)
  • feat: add jobFactory option for dependency injection support (c1563b5)
  • docs: add JSDoc documentation to public APIs (592f4b9)
  • refactor!: extract magic numbers into named constants (df0688c)
  • fix: improve graceful shutdown in Worker (12c46f6)
  • chore: update lock file (ccdc019)
  • ci: add GitHub Actions workflow for checks (5bf7db3)
  • chore: add logger information (e23fbeb)
  • fix: improve error handling in QueueManager (658488d)
  • feat: add injectable logger system (e89f662)
  • feat: export errors and types for better DX (892fcf8)
  • test: add worker concurrency tests to prevent job duplication (d736521)
  • refactor: make locations optional in QueueManagerConfig (6d3be20)
  • fix(knex): prevent race condition with FOR UPDATE SKIP LOCKED (379dc03)
  • feat: add stalled jobs recovery mechanism (5b0970f)
  • fix(redis): remove unsafe popAndWait method with race condition (dd2bfa8)
  • chore: add drivers as peer deps (109bc08)