diff --git a/packages/api/src/handlers/addJob.ts b/packages/api/src/handlers/addJob.ts new file mode 100644 index 00000000..a45810ee --- /dev/null +++ b/packages/api/src/handlers/addJob.ts @@ -0,0 +1,23 @@ +import { BaseAdapter } from '../queueAdapters/base'; +import { BullBoardRequest, ControllerHandlerReturnType } from '../../typings/app'; +import { queueProvider } from '../providers/queue'; +import { formatJob } from './queues'; + +async function addJob( + req: BullBoardRequest, + queue: BaseAdapter +): Promise { + const { name, data, options } = req.body; + + const job = await queue.addJob(name, data, options); + + return { + status: 200, + body: { + job: formatJob(job, queue), + status: job.getState(), + }, + }; +} + +export const addJobHandler = queueProvider(addJob); diff --git a/packages/api/src/queueAdapters/base.ts b/packages/api/src/queueAdapters/base.ts index 82e7d2e9..ecb22a94 100644 --- a/packages/api/src/queueAdapters/base.ts +++ b/packages/api/src/queueAdapters/base.ts @@ -5,6 +5,7 @@ import { JobStatus, QueueAdapterOptions, QueueJob, + QueueJobOptions, Status, } from '../../typings/app'; @@ -45,6 +46,8 @@ export abstract class BaseAdapter { public abstract clean(queueStatus: JobCleanStatus, graceTimeMs: number): Promise; + public abstract addJob(name: string, data: any, options: QueueJobOptions): Promise; + public abstract getJob(id: string): Promise; public abstract getJobCounts(): Promise; diff --git a/packages/api/src/queueAdapters/bull.ts b/packages/api/src/queueAdapters/bull.ts index 7cf30111..af57bbc2 100644 --- a/packages/api/src/queueAdapters/bull.ts +++ b/packages/api/src/queueAdapters/bull.ts @@ -4,6 +4,7 @@ import { JobCounts, JobStatus, QueueAdapterOptions, + QueueJobOptions, Status, } from '../../typings/app'; import { STATUSES } from '../constants/statuses'; @@ -26,6 +27,10 @@ export class BullAdapter extends BaseAdapter { return this.queue.clean(graceTimeMs, jobStatus as any); } + public addJob(name: string, data: any, options: QueueJobOptions) { + return this.queue.add(name, data, options); + } + public getJob(id: string): Promise { return this.queue.getJob(id).then((job) => job && this.alignJobData(job)); } diff --git a/packages/api/src/queueAdapters/bullMQ.ts b/packages/api/src/queueAdapters/bullMQ.ts index 357a9391..d25815f3 100644 --- a/packages/api/src/queueAdapters/bullMQ.ts +++ b/packages/api/src/queueAdapters/bullMQ.ts @@ -4,6 +4,7 @@ import { JobCounts, JobStatus, QueueAdapterOptions, + QueueJobOptions, Status, } from '../../typings/app'; import { STATUSES } from '../constants/statuses'; @@ -27,6 +28,10 @@ export class BullMQAdapter extends BaseAdapter { await this.queue.clean(graceTimeMs, 1000, jobStatus); } + public addJob(name: string, data: any, options: QueueJobOptions) { + return this.queue.add(name, data, options); + } + public getJob(id: string): Promise { return this.queue.getJob(id); } diff --git a/packages/api/src/routes.ts b/packages/api/src/routes.ts index 421b7745..5990488e 100644 --- a/packages/api/src/routes.ts +++ b/packages/api/src/routes.ts @@ -1,4 +1,5 @@ import { AppRouteDefs } from '../typings/app'; +import { addJobHandler } from './handlers/addJob'; import { cleanAllHandler } from './handlers/cleanAll'; import { cleanJobHandler } from './handlers/cleanJob'; import { emptyQueueHandler } from './handlers/emptyQueue'; @@ -33,6 +34,11 @@ export const appRoutes: AppRouteDefs = { route: '/api/queues/:queueName/:jobId', handler: jobHandler, }, + { + method: 'post', + route: '/api/queues/:queueName/add', + handler: addJobHandler, + }, { method: 'put', route: '/api/queues/:queueName/retry/:queueStatus', diff --git a/packages/api/typings/app.ts b/packages/api/typings/app.ts index 7a7244d9..b9601afd 100644 --- a/packages/api/typings/app.ts +++ b/packages/api/typings/app.ts @@ -71,6 +71,11 @@ export interface QueueJobJson { parentKey?: string; } +export interface QueueJobOptions { + delay?: number; + attempts?: number; +} + export interface RedisStats { version: string; mode: RedisInfo['redis_mode']; @@ -127,6 +132,7 @@ export interface BullBoardRequest { queues: BullBoardQueues; query: Record; params: Record; + body: Record; } export type ControllerHandlerReturnType = {