torotask
Version:
Task queue processing in NodeJS based on BullMQ and Redis
89 lines • 3.48 kB
JavaScript
import { StepExecutor } from './step-executor.js';
// --- SubTask Class ---
/**
* Represents a defined SubTask within a parent Task.
* Provides methods to enqueue jobs specifically for this subtask's handler,
* utilizing the parent Task's queue.
*
* @template DataType The expected type of the data payload for this subtask.
* @template ResultType The expected return type of the job associated with this subtask.
*/
export class SubTask {
parentTask; // Keep less specific for simplicity
id;
handler; // Uses imported type
logger;
constructor(parentTask, id, handler) {
if (!parentTask) {
throw new Error('Parent Task instance is required for SubTask.');
}
if (!id) {
throw new Error('SubTask id is required.');
}
if (!handler || typeof handler !== 'function') {
throw new Error('SubTask handler is required and must be a function.');
}
this.parentTask = parentTask;
this.id = id;
this.handler = handler;
// Inherit logger from parent task and add subtask context
this.logger = parentTask.logger.child({ subTaskId: this.id });
this.logger.info('SubTask defined');
}
/**
* Adds a job to the parent task's queue, specifically targeting this subtask's handler.
*
* @param data The data payload for the job.
* @param overrideOptions Optional JobOptions to override the parent task's defaults.
* @returns A promise resolving to the enqueued BullMQ Job object.
*/
async run(payload, overrideOptions) {
const finalOptions = {
...this.parentTask.jobsOptions,
...overrideOptions,
};
const data = {
payload,
};
// Call parent task's public helper method directly
return this.parentTask.queue.add(this.id, data, finalOptions);
}
async processSubJob(job, jobName, jobLogger) {
const stepExecutor = new StepExecutor(job, this.parentTask);
const handlerOptions = { id: job.id, name: jobName, payload: job.payload };
const handlerContext = {
logger: jobLogger,
client: this.parentTask.taskClient,
group: this.parentTask.group,
parentTask: this.parentTask,
subTaskId: this.id,
job: job,
step: stepExecutor,
queue: this.parentTask.queue,
};
try {
return await this.handler(handlerOptions, handlerContext);
}
catch (error) {
jobLogger.error({ err: error instanceof Error ? error : new Error(String(error)) }, `Job processing failed for job name "${job.name}"`);
throw error;
}
}
/**
* Adds a job for this subtask and waits for it to complete.
*
* @param data The data payload for the job.
* @param overrideOptions Optional JobOptions to override the parent task's defaults.
* @returns A promise resolving to the return value of the completed job.
* @throws Throws an error if the job fails or cannot be awaited.
*/
async runAndWait(data, overrideOptions) {
const finalOptions = {
...this.parentTask.jobsOptions,
...overrideOptions,
};
// Call parent task's public helper method directly
return this.parentTask.queue._runJobAndWait(this.id, data, finalOptions);
}
}
//# sourceMappingURL=sub-task.js.map