@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
TypeScript
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 };