UNPKG

@sidequest/engine

Version:

@sidequest/engine is the core engine of SideQuest, a distributed background job processing system for Node.js and TypeScript.

170 lines (167 loc) 7.49 kB
import * as _sidequest_backend from '@sidequest/backend'; import { BackendConfig, NewQueueData } from '@sidequest/backend'; import { LoggerOptions, JobClassType } from '@sidequest/core'; import { JobBuilderDefaults, JobBuilder } from './job/job-builder.js'; import { QueueDefaults } from './queue/grant-queue-config.js'; /** * Configuration options for the Sidequest engine. */ interface EngineConfig { /** Backend configuration. Defaults to `@sidequest/sqlite-backend` and `./sidequest.sqlite` file */ backend?: BackendConfig; /** List of queue configurations. Defaults to `[]` */ queues?: NewQueueData[]; /** Logger configuration options. Defaults to `info` and no json */ logger?: LoggerOptions; /** Maximum number of concurrent jobs. Defaults to `10` */ maxConcurrentJobs?: number; /** Whether to skip migration when starting the engine. Defaults to `false` */ skipMigration?: boolean; /** Frequency in minutes for releasing stale jobs. Set to false to disable. Defaults to 60 min */ releaseStaleJobsIntervalMin?: number | false; /** Maximum age in milliseconds a running job must be to be considered a stale job. Defaults to 10 minutes */ releaseStaleJobsMaxStaleMs?: number; /** Maximum age in milliseconds a claimed job must be to be considered stale. Defaults to 1 minute */ releaseStaleJobsMaxClaimedMs?: number; /** Frequency in minutes for cleaning up finished jobs. Set to false to disable. Defaults to 60 min */ cleanupFinishedJobsIntervalMin?: number | false; /** Time in milliseconds to clean up finished jobs older than this value. Defaults to 30 days */ cleanupFinishedJobsOlderThan?: number; /** Whether to enable graceful shutdown handling. Defaults to `true` */ gracefulShutdown?: boolean; /** Minimum number of worker threads to use. Defaults to number of CPUs */ minThreads?: number; /** Maximum number of worker threads to use. Defaults to `minThreads * 2` */ maxThreads?: number; /** Timeout in milliseconds for idle workers before they are terminated. Defaults to 10 seconds */ idleWorkerTimeout?: number; /** * Default job builder configuration. * This allows setting default values for job properties like queue, timeout, uniqueness, etc. * If not provided during job build, defaults will be used. * * @see {@link JobBuilderDefaults} for more details */ jobDefaults?: JobBuilderDefaults; /** * Default queue configuration. * This allows setting default values for queue properties like concurrency, priority, etc. * If not provided during queue creation, defaults will be used. * * @see {@link QueueDefaults} for more details */ queueDefaults?: QueueDefaults; /** * If true, job scripts will NOT be automatically resolved by the engine. * In this case, you need to create a `sidequest.jobs.js` file at the root of your project * (and at the root of any other project that uses Sidequest, like a worker) that imports and * exports all job classes. * * This allows you to control exactly which job classes are available to Sidequest, * and can also solve issues with module resolution in certain environments. * * Defaults to `false`. */ manualJobResolution?: boolean; /** * Optional path to the `sidequest.jobs.js` file when using manual job resolution. * If not provided, the engine will search for `sidequest.jobs.js` starting from the current working directory * and walking up through parent directories until it finds the file or reaches the root. * * This is useful if your `sidequest.jobs.js` file is located in a non-standard location * or if you want to explicitly specify its path. * * This option will be resolved and changed at configuration time, and if the file does not exist, * an error will be thrown. * * IMPORTANT: if a relative path is provided, it will be resolved relative to the file calling the engine or * `Sidequest.configure()`, NOT the current working directory. * * If manualJobResolution === false, this option is ignored. */ jobsFilePath?: string; /** * Interval in milliseconds for polling new jobs in the dispatcher loop. * The dispatcher will check for new jobs in the DB to process at every polling cycle. * * Increase this number to reduce DB load at the cost of job start latency. * Decrease this number if you want to have lower latency at the cost of higher DB load. * * Defaults to 100 ms. */ jobPollingInterval?: number; } /** * Non-nullable version of the EngineConfig type. * Ensures all properties are defined and not null. * * @see {@link EngineConfig} for the original type. */ type NonNullableEngineConfig = { [P in keyof EngineConfig]-?: NonNullable<EngineConfig[P]>; }; /** * The main engine for managing job queues and workers in Sidequest. */ declare class Engine { /** * Main worker process that runs the Sidequest engine. * This is created when the engine is started and handles job processing. */ private mainWorker?; /** * Flag indicating whether the engine is currently shutting down. * This is used to prevent multiple shutdown attempts and ensure graceful shutdown behavior. */ private shuttingDown; /** * Configures the Sidequest engine with the provided configuration. * @param config Optional configuration object. * @returns The resolved configuration. */ configure(config?: EngineConfig): Promise<NonNullableEngineConfig>; /** * Validates the engine configuration settings. * * This method also resolves the jobs file path to a file URL if manual job resolution is enabled. * * @throws {Error} When `maxConcurrentJobs` is defined but less than 1 * @throws {Error} When `manualJobResolution` is enabled but the specified `jobsFilePath` does not exist * @throws {Error} When `manualJobResolution` is enabled but no jobs script can be found in parent directories * * @remarks * - Ensures `maxConcurrentJobs` is at least 1 if specified * - When `manualJobResolution` is enabled, validates that either: * - A valid `jobsFilePath` exists and resolves it to an absolute URL * - A sidequest jobs script can be found in parent directories * - Logs the resolved jobs file path when using manual job resolution */ validateConfig(): void; /** * Starts the Sidequest engine and worker process. * @param config Optional configuration object. */ start(config: EngineConfig): Promise<void>; /** * Gets the current engine configuration. * @returns The current configuration, if set. */ getConfig(): NonNullableEngineConfig | undefined; /** * Gets the backend instance in use by the engine. * @returns The backend instance, if set. */ getBackend(): _sidequest_backend.Backend | undefined; /** * Closes the engine and releases resources. */ close(): Promise<void>; /** * Builds a job using the provided job class. * @param JobClass The job class constructor. * @returns A new JobBuilder instance for the job class. */ build<T extends JobClassType>(JobClass: T): JobBuilder<T>; } export { Engine }; export type { EngineConfig, NonNullableEngineConfig };