@opens/bullmq 3.1.2 → 3.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -2,11 +2,17 @@ import * as BullMQ from 'bullmq';
2
2
  import { Redis } from 'ioredis';
3
3
  import { observer } from '@opens/observability';
4
4
 
5
+ type FlowNode = {
6
+ taskName: string;
7
+ taskData: any;
8
+ taskOptions?: BullMQ.JobsOptions;
9
+ };
5
10
  declare class BullMQWrapper {
6
11
  private taskQueues;
7
12
  private taskWorkers;
8
13
  private defaultConnection?;
9
14
  private observer?;
15
+ private flowProducer?;
10
16
  start(params?: {
11
17
  connection?: Redis;
12
18
  oberserver?: typeof observer;
@@ -51,6 +57,23 @@ declare class BullMQWrapper {
51
57
  }): {
52
58
  worker: BullMQ.Worker<any, void, string>;
53
59
  };
60
+ /**
61
+ * Builds a single FlowProducer job node from task info.
62
+ */
63
+ prepareTask(node: FlowNode): BullMQ.FlowJob;
64
+ publishFlow(params: {
65
+ parent: BullMQ.FlowJob;
66
+ children: BullMQ.FlowJob[];
67
+ }): Promise<BullMQ.JobNode>;
68
+ publish(params: {
69
+ taskData: any;
70
+ taskId?: string;
71
+ taskName: string;
72
+ taskOptions?: BullMQ.JobsOptions;
73
+ } | {
74
+ parent: BullMQ.FlowJob;
75
+ children: BullMQ.FlowJob[];
76
+ }): Promise<BullMQ.JobJson | BullMQ.JobNode | null>;
54
77
  publishTask(params: {
55
78
  taskData: any;
56
79
  taskId?: string;
package/dist/index.js CHANGED
@@ -82,6 +82,7 @@ var BullMQWrapper = class {
82
82
  taskWorkers = /* @__PURE__ */ new Map();
83
83
  defaultConnection;
84
84
  observer;
85
+ flowProducer;
85
86
  start(params = {}) {
86
87
  if (this.defaultConnection) {
87
88
  this.defaultConnection?.disconnect();
@@ -170,6 +171,26 @@ var BullMQWrapper = class {
170
171
  this.taskWorkers.set(taskName, worker);
171
172
  return { worker };
172
173
  }
174
+ /**
175
+ * Builds a single FlowProducer job node from task info.
176
+ */
177
+ prepareTask(node) {
178
+ return {
179
+ name: node.taskName,
180
+ queueName: node.taskName,
181
+ data: node.taskData,
182
+ opts: node.taskOptions ?? this.taskQueues.get(node.taskName)?.opts.defaultJobOptions
183
+ };
184
+ }
185
+ async publishFlow(params) {
186
+ if (!this.defaultConnection) throw new Error("Default connection is not set. Please call start() method first.");
187
+ if (!this.flowProducer) this.flowProducer = new BullMQ.FlowProducer({ connection: this.defaultConnection });
188
+ return this.flowProducer.add({ ...params.parent, children: params.children });
189
+ }
190
+ async publish(params) {
191
+ if ("parent" in params) return this.publishFlow(params);
192
+ return this.publishTask(params);
193
+ }
173
194
  async publishTask(params) {
174
195
  const queue = this.taskQueues.get(params.taskName);
175
196
  if (!queue) return null;
@@ -192,6 +213,7 @@ var BullMQWrapper = class {
192
213
  this.taskWorkers.forEach((worker) => {
193
214
  promises.push(worker.close());
194
215
  });
216
+ if (this.flowProducer) promises.push(this.flowProducer.close());
195
217
  promises.push(this.defaultConnection.quit());
196
218
  await Promise.all(promises);
197
219
  console.log(`[@opens/bullmq]: all workers closed`);
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/wrapper.ts","../src/default-connection.ts"],"sourcesContent":["import { BullMQWrapper } from './wrapper';\nexport const bullmq = new BullMQWrapper();\n","import * as BullMQ from 'bullmq';\nimport { Redis } from 'ioredis';\nimport { observer, TRACE_TYPE } from '@opens/observability';\nimport { DefaultConnection } from './default-connection';\nexport class BullMQWrapper {\n private taskQueues: Map<string, BullMQ.Queue> = new Map();\n private taskWorkers: Map<string, BullMQ.Worker> = new Map();\n private defaultConnection?: Redis;\n private observer?: typeof observer;\n\n start(\n params:\n | { connection?: Redis; oberserver?: typeof observer }\n | { redis: { host?: string; port?: number; oberserver?: typeof observer } } = {},\n ) {\n if (this.defaultConnection) {\n this.defaultConnection?.disconnect();\n }\n\n if ('connection' in params && params.connection) {\n this.defaultConnection = params.connection;\n return;\n }\n\n if ('redis' in params) {\n this.defaultConnection = DefaultConnection.getInstance({ port: params.redis.port, host: params.redis.host });\n return;\n }\n this.observer = params.oberserver;\n this.defaultConnection = DefaultConnection.getInstance();\n }\n\n public createTask(params: {\n taskName: string;\n defaultOptions: BullMQ.DefaultJobOptions;\n connection?: Redis;\n up?: (data: any, job: BullMQ.Job) => Promise<void>;\n down?: (data: any, job: BullMQ.Job, err: unknown) => Promise<void>;\n concurrency?: number;\n removeOnCompleteAge?: number;\n removeOnCompleteCount?: number;\n removeOnFailAge?: number;\n removeOnFailCount?: number;\n tracer?: typeof observer.tracer;\n }) {\n if (!this.defaultConnection) throw new Error('Default connection is not set. Please call start() method first.');\n\n const { taskName, up, down, defaultOptions, connection, concurrency } = params;\n if (this.taskQueues.has(taskName)) return;\n\n const queue = new BullMQ.Queue(taskName, {\n connection: this.defaultConnection ?? connection,\n defaultJobOptions: { backoff: { delay: 1000 * 60 * 5, type: 'fixed' }, attempts: 10, ...defaultOptions },\n });\n this.taskQueues.set(taskName, queue);\n console.debug(`[@opens/bullmq]: task queue'${taskName}' created`);\n if (!up) return { queue };\n\n const { worker } = this.createWorker({\n up,\n down,\n concurrency: concurrency ?? 1,\n ...params,\n });\n return { queue, worker };\n }\n\n public createWorker(params: {\n taskName: string;\n up: (data: any, job: BullMQ.Job) => Promise<void>;\n down?: (data: any, job: BullMQ.Job, err: unknown) => Promise<void>;\n connection?: Redis;\n concurrency: number;\n tracer?: typeof observer.tracer;\n removeOnCompleteAge?: number;\n removeOnCompleteCount?: number;\n removeOnFailAge?: number;\n removeOnFailCount?: number;\n onError?: Function;\n }) {\n if (!this.defaultConnection) throw new Error('Default connection is not set. Please call start() method first.');\n const {\n taskName,\n up,\n down,\n concurrency,\n connection,\n removeOnFailCount,\n removeOnCompleteAge,\n removeOnCompleteCount,\n removeOnFailAge,\n tracer,\n } = params;\n\n const registeredQueue = this.taskQueues.get(taskName);\n if (!registeredQueue) throw new Error(`No task queue for [${taskName}] found`);\n const fn = async (job: BullMQ.Job) => {\n try {\n await up(job.data, job);\n } catch (error) {\n if (down) await down(job.data, job, error);\n throw error;\n } finally {\n }\n };\n const trace = tracer ?? this.observer?.tracer;\n const handler = trace?.instrumentAsyncFunc({ name: taskName, type: TRACE_TYPE.TASK }, fn) ?? fn;\n\n const worker = new BullMQ.Worker(taskName, handler, {\n concurrency,\n connection: connection ?? this.defaultConnection,\n removeOnComplete: {\n age: removeOnCompleteAge ?? 60 * 60,\n count: removeOnCompleteCount ?? 20,\n },\n removeOnFail: {\n age: removeOnFailAge ?? 60 * 60,\n count: removeOnFailCount ?? 50,\n },\n });\n worker.on('ready', () => {\n console.log(`[opens/bullmq]: '${taskName}' worker is ready`);\n });\n worker.on('error', (err) => {\n console.error('[opens/bullmq]: error', err);\n });\n worker.on('ioredis:close', () => {\n console.log('[opens/bullmq]: redis has closed');\n });\n worker.on('closed', () => {\n console.log('[opens/bullmq]: worker closed');\n });\n this.taskWorkers.set(taskName, worker);\n return { worker };\n }\n\n public async publishTask(params: {\n taskData: any;\n taskId?: string;\n taskName: string;\n taskOptions?: BullMQ.JobsOptions;\n }) {\n const queue = this.taskQueues.get(params.taskName);\n if (!queue) return null;\n const jobName = params.taskId ? `${params.taskName}_${params.taskId}` : '';\n const job = await queue.add(jobName, params.taskData, params.taskOptions);\n return job.asJSON();\n }\n\n public getTaskCount() {\n return this.taskQueues.size;\n }\n\n public async removeDeduplication(params: { taskName: string; deduplicationId: string }) {\n const queue = this.taskQueues.get(params.taskName);\n if (!queue) return 0;\n const result = await queue.removeDeduplicationKey(params.deduplicationId);\n return result;\n }\n\n public async shutdown() {\n if (!this.defaultConnection) throw new Error('Default connection is not set. Please call start() method first.');\n const promises: Promise<any>[] = [];\n this.taskWorkers.forEach((worker) => {\n promises.push(worker.close());\n });\n promises.push(this.defaultConnection.quit());\n await Promise.all(promises);\n console.log(`[@opens/bullmq]: all workers closed`);\n }\n\n public getConnection() {\n return this.defaultConnection;\n }\n}\n","import { Redis } from 'ioredis';\nexport class DefaultConnection {\n static getInstance(params: { host?: string; port?: number } = {}): Redis {\n const host = params.host ?? process.env.BULLMQ_REDIS_HOST;\n const port = params.port ?? parseInt(process.env.BULLMQ_REDIS_PORT ?? '6379', 10);\n const redis = new Redis({\n host,\n port,\n maxRetriesPerRequest: null,\n retryStrategy(times: number) {\n const value = Math.max(Math.min(Math.exp(times), 20000), 1000);\n console.log(`[redis]: retry stretegy callback value: ${value}`);\n return value;\n },\n });\n redis.on('close', () => {\n console.log('[redis]: closed');\n });\n redis.on('reconnecting', () => {\n console.log('[redis]: reconnecting');\n });\n redis.on('connect', () => {\n console.log('[redis]: connected');\n });\n redis.on('error', (err) => {\n console.log('[redis]: error', err);\n });\n redis.on('connecting', () => {\n console.log('[redis]: connecting');\n });\n redis.on('ready', () => {\n console.log('[redis]: ready');\n });\n return redis;\n }\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/index.ts","../src/wrapper.ts","../src/default-connection.ts"],"sourcesContent":["import { BullMQWrapper } from './wrapper';\nexport const bullmq = new BullMQWrapper();\n","import * as BullMQ from 'bullmq';\nimport { Redis } from 'ioredis';\nimport { observer, TRACE_TYPE } from '@opens/observability';\nimport { DefaultConnection } from './default-connection';\n\ntype FlowNode = {\n taskName: string;\n taskData: any;\n taskOptions?: BullMQ.JobsOptions;\n};\n\nexport class BullMQWrapper {\n private taskQueues: Map<string, BullMQ.Queue> = new Map();\n private taskWorkers: Map<string, BullMQ.Worker> = new Map();\n private defaultConnection?: Redis;\n private observer?: typeof observer;\n private flowProducer?: BullMQ.FlowProducer;\n\n start(\n params:\n | { connection?: Redis; oberserver?: typeof observer }\n | { redis: { host?: string; port?: number; oberserver?: typeof observer } } = {},\n ) {\n if (this.defaultConnection) {\n this.defaultConnection?.disconnect();\n }\n\n if ('connection' in params && params.connection) {\n this.defaultConnection = params.connection;\n return;\n }\n\n if ('redis' in params) {\n this.defaultConnection = DefaultConnection.getInstance({ port: params.redis.port, host: params.redis.host });\n return;\n }\n this.observer = params.oberserver;\n this.defaultConnection = DefaultConnection.getInstance();\n }\n\n public createTask(params: {\n taskName: string;\n defaultOptions: BullMQ.DefaultJobOptions;\n connection?: Redis;\n up?: (data: any, job: BullMQ.Job) => Promise<void>;\n down?: (data: any, job: BullMQ.Job, err: unknown) => Promise<void>;\n concurrency?: number;\n removeOnCompleteAge?: number;\n removeOnCompleteCount?: number;\n removeOnFailAge?: number;\n removeOnFailCount?: number;\n tracer?: typeof observer.tracer;\n }) {\n if (!this.defaultConnection) throw new Error('Default connection is not set. Please call start() method first.');\n\n const { taskName, up, down, defaultOptions, connection, concurrency } = params;\n if (this.taskQueues.has(taskName)) return;\n\n const queue = new BullMQ.Queue(taskName, {\n connection: this.defaultConnection ?? connection,\n defaultJobOptions: { backoff: { delay: 1000 * 60 * 5, type: 'fixed' }, attempts: 10, ...defaultOptions },\n });\n this.taskQueues.set(taskName, queue);\n console.debug(`[@opens/bullmq]: task queue'${taskName}' created`);\n if (!up) return { queue };\n\n const { worker } = this.createWorker({\n up,\n down,\n concurrency: concurrency ?? 1,\n ...params,\n });\n return { queue, worker };\n }\n\n public createWorker(params: {\n taskName: string;\n up: (data: any, job: BullMQ.Job) => Promise<void>;\n down?: (data: any, job: BullMQ.Job, err: unknown) => Promise<void>;\n connection?: Redis;\n concurrency: number;\n tracer?: typeof observer.tracer;\n removeOnCompleteAge?: number;\n removeOnCompleteCount?: number;\n removeOnFailAge?: number;\n removeOnFailCount?: number;\n onError?: Function;\n }) {\n if (!this.defaultConnection) throw new Error('Default connection is not set. Please call start() method first.');\n const {\n taskName,\n up,\n down,\n concurrency,\n connection,\n removeOnFailCount,\n removeOnCompleteAge,\n removeOnCompleteCount,\n removeOnFailAge,\n tracer,\n } = params;\n\n const registeredQueue = this.taskQueues.get(taskName);\n if (!registeredQueue) throw new Error(`No task queue for [${taskName}] found`);\n const fn = async (job: BullMQ.Job) => {\n try {\n await up(job.data, job);\n } catch (error) {\n if (down) await down(job.data, job, error);\n throw error;\n } finally {\n }\n };\n const trace = tracer ?? this.observer?.tracer;\n const handler = trace?.instrumentAsyncFunc({ name: taskName, type: TRACE_TYPE.TASK }, fn) ?? fn;\n\n const worker = new BullMQ.Worker(taskName, handler, {\n concurrency,\n connection: connection ?? this.defaultConnection,\n removeOnComplete: {\n age: removeOnCompleteAge ?? 60 * 60,\n count: removeOnCompleteCount ?? 20,\n },\n removeOnFail: {\n age: removeOnFailAge ?? 60 * 60,\n count: removeOnFailCount ?? 50,\n },\n });\n worker.on('ready', () => {\n console.log(`[opens/bullmq]: '${taskName}' worker is ready`);\n });\n worker.on('error', (err) => {\n console.error('[opens/bullmq]: error', err);\n });\n worker.on('ioredis:close', () => {\n console.log('[opens/bullmq]: redis has closed');\n });\n worker.on('closed', () => {\n console.log('[opens/bullmq]: worker closed');\n });\n this.taskWorkers.set(taskName, worker);\n return { worker };\n }\n\n /**\n * Builds a single FlowProducer job node from task info.\n */\n public prepareTask(node: FlowNode): BullMQ.FlowJob {\n return {\n name: node.taskName,\n queueName: node.taskName,\n data: node.taskData,\n opts: node.taskOptions ?? this.taskQueues.get(node.taskName)?.opts.defaultJobOptions,\n };\n }\n\n public async publishFlow(params: { parent: BullMQ.FlowJob; children: BullMQ.FlowJob[] }) {\n if (!this.defaultConnection) throw new Error('Default connection is not set. Please call start() method first.');\n\n if (!this.flowProducer) this.flowProducer = new BullMQ.FlowProducer({ connection: this.defaultConnection });\n\n return this.flowProducer.add({ ...params.parent, children: params.children });\n }\n\n public async publish(\n params:\n | { taskData: any; taskId?: string; taskName: string; taskOptions?: BullMQ.JobsOptions }\n | { parent: BullMQ.FlowJob; children: BullMQ.FlowJob[] },\n ) {\n if ('parent' in params) return this.publishFlow(params);\n return this.publishTask(params);\n }\n\n public async publishTask(params: {\n taskData: any;\n taskId?: string;\n taskName: string;\n taskOptions?: BullMQ.JobsOptions;\n }) {\n const queue = this.taskQueues.get(params.taskName);\n if (!queue) return null;\n const jobName = params.taskId ? `${params.taskName}_${params.taskId}` : '';\n const job = await queue.add(jobName, params.taskData, params.taskOptions);\n return job.asJSON();\n }\n\n public getTaskCount() {\n return this.taskQueues.size;\n }\n\n public async removeDeduplication(params: { taskName: string; deduplicationId: string }) {\n const queue = this.taskQueues.get(params.taskName);\n if (!queue) return 0;\n const result = await queue.removeDeduplicationKey(params.deduplicationId);\n return result;\n }\n\n public async shutdown() {\n if (!this.defaultConnection) throw new Error('Default connection is not set. Please call start() method first.');\n const promises: Promise<any>[] = [];\n this.taskWorkers.forEach((worker) => {\n promises.push(worker.close());\n });\n if (this.flowProducer) promises.push(this.flowProducer.close());\n promises.push(this.defaultConnection.quit());\n await Promise.all(promises);\n console.log(`[@opens/bullmq]: all workers closed`);\n }\n\n public getConnection() {\n return this.defaultConnection;\n }\n}\n","import { Redis } from 'ioredis';\nexport class DefaultConnection {\n static getInstance(params: { host?: string; port?: number } = {}): Redis {\n const host = params.host ?? process.env.BULLMQ_REDIS_HOST;\n const port = params.port ?? parseInt(process.env.BULLMQ_REDIS_PORT ?? '6379', 10);\n const redis = new Redis({\n host,\n port,\n maxRetriesPerRequest: null,\n retryStrategy(times: number) {\n const value = Math.max(Math.min(Math.exp(times), 20000), 1000);\n console.log(`[redis]: retry stretegy callback value: ${value}`);\n return value;\n },\n });\n redis.on('close', () => {\n console.log('[redis]: closed');\n });\n redis.on('reconnecting', () => {\n console.log('[redis]: reconnecting');\n });\n redis.on('connect', () => {\n console.log('[redis]: connected');\n });\n redis.on('error', (err) => {\n console.log('[redis]: error', err);\n });\n redis.on('connecting', () => {\n console.log('[redis]: connecting');\n });\n redis.on('ready', () => {\n console.log('[redis]: ready');\n });\n return redis;\n }\n}\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opens/bullmq",
3
- "version": "3.1.2",
3
+ "version": "3.1.4",
4
4
  "description": "A wrapper around bullmq",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
@@ -24,6 +24,7 @@
24
24
  "author": "Joao Victor Clementino",
25
25
  "license": "ISC",
26
26
  "devDependencies": {
27
+ "@opens/observability": "^1.1.1",
27
28
  "ioredis-mock": "^8.9.0",
28
29
  "tsup": "^8.3.5",
29
30
  "typescript": "^5.7.3",
@@ -45,4 +46,4 @@
45
46
  "optional": true
46
47
  }
47
48
  }
48
- }
49
+ }