UNPKG

torotask

Version:

Task queue processing in NodeJS based on BullMQ and Redis

217 lines 11.2 kB
import type { ConnectionOptions } from 'bullmq'; import type { Logger } from 'pino'; import type { TaskJob } from './job.js'; import type { Task } from './task.js'; import type { SchemaHandler, TaskDefinitionRegistry, TaskFlowRun, TaskFlowRunNode, TaskGroupDefinitionRegistry, TaskGroupRegistry, TaskJobOptions, TaskRegistry, ToroTaskOptions } from './types/index.js'; import { EventEmitter } from 'node:events'; import { Redis } from 'ioredis'; import { EventDispatcher } from './event-dispatcher.js'; import { TaskQueue } from './queue.js'; import { TaskGroup } from './task-group.js'; import { TaskWorkflow } from './workflow.js'; /** * A client class to manage BullMQ connection settings, TaskGroups, and an EventDispatcher. */ export declare class ToroTask<TAllTaskGroupsDefs extends TaskGroupDefinitionRegistry = TaskGroupDefinitionRegistry, TGroups extends TaskGroupRegistry<TAllTaskGroupsDefs> = TaskGroupRegistry<TAllTaskGroupsDefs>> extends EventEmitter { readonly connectionOptions: ConnectionOptions; readonly logger: Logger; readonly prefix: string; readonly queuePrefix: string; private _eventDispatcher; private _workflow; private _redis; private _consumerQueues; readonly taskGroups: TGroups; private readonly _isTyped; private readonly _allowNonExistingQueues; private readonly _eventOptions?; private readonly _reuseConnections; private _sharedQueueRedisInstance; private _sharedWorkerRedisInstance; private _createdConnections; private _queueDiscoverySubscriber; private _isQueueDiscoveryActive; private _knownQueues; constructor(options?: ToroTaskOptions, taskGroupDefs?: TAllTaskGroupsDefs); /** * Initializes task groups from the provided task group definitions. * This creates all task groups and their tasks, and adds them to the server. */ private initializeTaskGroups; /** * Gets the lazily-initialized EventDispatcher instance. * Creates the instance on first access. */ get events(): EventDispatcher; /** * Gets the lazily-initialized TaskWorkflow instance. * Creates the instance on first access. */ get workflow(): TaskWorkflow; /** * Gets the resolved connection options suitable for BullMQ. */ getConnectionOptions(): ConnectionOptions; /** * Gets the Redis client instance, transparently handling connection reusing. * When connection reusing is enabled, returns the shared Redis instance for queues. * When disabled, returns the dedicated main Redis client. */ get redis(): Redis; /** * Gets the shared Redis instance for BullMQ Queue connection reusing. * Returns undefined when connection reusing is disabled. */ getSharedQueueRedisInstance(): Redis | undefined; /** * Gets the shared Redis instance for BullMQ Worker connection reusing. * Workers need maxRetriesPerRequest: null for persistent connections. * Returns undefined when connection reusing is disabled. */ getSharedWorkerRedisInstance(): Redis | undefined; /** * Creates or retrieves a TaskGroup instance. */ createTaskGroup<TDefs extends TaskDefinitionRegistry>(id: string, definitions?: TDefs): TaskGroup<TDefs, TaskRegistry<TDefs>>; /** * Retrieves an existing TaskGroup instance by id. */ getTaskGroup<G extends keyof TGroups, SpecificTaskGroup extends TGroups[G] = TGroups[G]>(id: G): SpecificTaskGroup | undefined; /** * Retrieves an existing Task instance by group and id (internal method). * Note: This method now uses the task id since we've unified key and ID concepts. * @internal */ private _getTask; getTask<G extends keyof TGroups, SpecificTaskGroup extends TGroups[G] = TGroups[G], TaskName extends keyof SpecificTaskGroup['tasks'] = keyof SpecificTaskGroup['tasks']>(groupId: G, taskId: TaskName): SpecificTaskGroup['tasks'][TaskName] | undefined; /** * Gets a task in the specified group with the provided path. * * @param taskPath The path of the task to get in format group.task. * @returns The Task instance if found, otherwise undefined. */ getTaskByPath<PayloadType = any, ResultType = unknown>(taskPath: `${string}.${string}`): Task<PayloadType, ResultType, SchemaHandler> | undefined; /** * Checks if a queue exists in Redis. * * @param queueName The name of the queue to check. * @returns A promise that resolves to a boolean indicating if the queue exists. */ private queueExists; /** * Retrieves a consumer queue, creating it if it doesn't exist. * * @param group The group id of the task. * @param task The task id. * @returns A promise that resolves to the Queue instance or null if it doesn't exist. */ private getConsumerQueue; getJobById<PayloadType = any, ResultType = any>(queueName: string, jobId: string): Promise<TaskJob<PayloadType, ResultType> | undefined>; /** * Gets all child jobs for a specific parent job from a given queue. * Used primarily for optimized reconstruction of bulk job references. * * @param queueName The name of the queue to search in * @param parentId The ID of the parent job * @param afterTimestamp Optional timestamp to filter jobs created after this time * @returns Array of child jobs */ getChildJobs<PayloadType = any, ResultType = any>(queueName: string, parentId: string, afterTimestamp?: number): Promise<TaskJob<PayloadType, ResultType>[]>; /** * Runs a task in the specified group with the provided data (internal method). * * @param groupId The id of the task group. * @param taskId The id of the task to run. * @param payload The data to pass to the task. * @param options The options for the task job. * @returns A promise that resolves to the Job instance. * @internal */ private _runTask; /** * Runs a task in the specified group with the provided data. * * @param taskPath The id of the task to run in format group.task. * @param payload The data to pass to the task. * @returns A promise that resolves to the Job instance. */ runTaskByPath<PayloadType = any, ResultType = any>(taskPath: `${string}.${string}`, payload: PayloadType): Promise<TaskJob<any, any, string, import("./types/job.js").TaskJobData<any, import("./types/job.js").TaskJobState>, import("./types/job.js").TaskJobState> | TaskJob<unknown, ResultType, string, import("./types/job.js").TaskJobData<unknown, import("./types/job.js").TaskJobState>, import("./types/job.js").TaskJobState> | TaskJob<PayloadType, ResultType, string, import("./types/job.js").TaskJobData<PayloadType, import("./types/job.js").TaskJobState>, import("./types/job.js").TaskJobState>>; /** * Runs a task in the specified group with the provided data. * In typed mode, provides full type safety and uses local task instances when available. * In generic mode, allows any group/task combination and always uses queue-based execution. * * @param groupId The id of the task group. * @param taskName The name of the task to run. * @param payload The data to pass to the task. * @param options Optional job options for queue-based execution. * @returns A promise that resolves to the Job instance. */ runTask<G extends TAllTaskGroupsDefs extends undefined ? string : keyof TGroups, SpecificTaskGroup extends TAllTaskGroupsDefs extends undefined ? any : TGroups[G], TaskName extends TAllTaskGroupsDefs extends undefined ? string : keyof SpecificTaskGroup['tasks'], ActualTask extends TAllTaskGroupsDefs extends undefined ? any : SpecificTaskGroup['tasks'][TaskName], Payload = TAllTaskGroupsDefs extends undefined ? any : ActualTask extends Task<infer P, any, any> ? P : unknown, Result = TAllTaskGroupsDefs extends undefined ? any : ActualTask extends Task<any, infer R, any> ? R : unknown, ActualPayload extends Payload = Payload>(groupId: G, taskName: TaskName, payload: ActualPayload, options?: TaskJobOptions): Promise<TaskJob<ActualPayload, Result>>; /** * Runs multiple task in the specified groups with the provided data. * */ runFlow<TFlowRun extends TaskFlowRun<TAllTaskGroupsDefs> = TaskFlowRun<TAllTaskGroupsDefs>>(run: TFlowRun, options?: Partial<TaskJobOptions>): Promise<TaskFlowRunNode>; /** * Runs multiple task in the specified groups with the provided data. */ runFlows<TFlowRun extends TaskFlowRun<TAllTaskGroupsDefs> = TaskFlowRun<TAllTaskGroupsDefs>>(runs: TFlowRun[], options?: Partial<TaskJobOptions>): Promise<TaskFlowRunNode[]>; /** * Sends an event to the EventDispatcher. * This method is a wrapper around the EventDispatcher's send method. * It allows sending events with a specific name and data payload. * @param eventName * @param data * @param options * @returns A promise that resolves when the event is sent. */ sendEvent<E = unknown>(eventName: string, data: E, options?: TaskJobOptions): Promise<TaskJob<any, any, string, import("./types/job.js").TaskJobData<any, import("./types/job.js").TaskJobState>, import("./types/job.js").TaskJobState> | undefined>; /** * Fetches all BullMQ queue names from the Redis instance. * Uses shared client connection when connection reusing is enabled, otherwise uses main Redis client. * * @returns A promise that resolves with an array of unique queue names. */ getAllQueueNames(): Promise<string[]>; /** * Fetches all BullMQ queue names and returns a map of queue names to Queue instances. * * @returns A promise that resolves with a Record mapping queue names to Queue instances. */ getAllQueueInstances(): Promise<Record<string, TaskQueue>>; /** * Closes all managed TaskGroups, their Tasks, the EventDispatcher, Queues and redis gracefully. */ close(): Promise<void>; /** * Starts Redis keyspace notifications to listen for new queue creation. * Emits 'queueCreated' and 'queueRemoved' events when queues are detected. */ startQueueDiscovery(): Promise<void>; /** * Stops Redis keyspace notifications for queue discovery. */ stopQueueDiscovery(): Promise<void>; /** * Gets the list of currently known queue names from the discovery system. */ getKnownQueueNames(): string[]; /** * Checks if queue discovery is currently active. */ isQueueDiscoveryActive(): boolean; /** * Gets connection options optimized for BullMQ Queue usage. * Uses default maxRetriesPerRequest for quick failures in request-response scenarios. */ getQueueConnectionOptions(): ConnectionOptions; /** * Gets connection options optimized for BullMQ Worker usage. * Uses maxRetriesPerRequest: null for persistent connections that retry forever. */ getWorkerConnectionOptions(): ConnectionOptions; } export { EventDispatcher } from './event-dispatcher.js'; export { ConnectionOptions, Job, JobsOptions, Queue } from 'bullmq'; //# sourceMappingURL=client.d.ts.map