@pauldeng/node-red-contrib-bullmq 1.0.2 → 2.0.0

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.
@@ -8,7 +8,7 @@
8
8
  },
9
9
  {
10
10
  "id": "queue-bullmq-features",
11
- "type": "bull-queue-server",
11
+ "type": "bullmq-queue-server",
12
12
  "name": "bullmq-features",
13
13
  "deployment": "single",
14
14
  "address": "localhost",
@@ -30,7 +30,11 @@
30
30
  "type": "inject",
31
31
  "z": "flow-bullmq-features",
32
32
  "name": "delay: send later",
33
- "props": [{ "p": "payload" }],
33
+ "props": [
34
+ {
35
+ "p": "payload"
36
+ }
37
+ ],
34
38
  "repeat": "",
35
39
  "crontab": "",
36
40
  "once": false,
@@ -57,12 +61,80 @@
57
61
  "y": 100,
58
62
  "wires": [["cmd-feature-examples"]]
59
63
  },
64
+ {
65
+ "id": "inject-delay-series-example",
66
+ "type": "inject",
67
+ "z": "flow-bullmq-features",
68
+ "name": "delay: series of one-off jobs",
69
+ "props": [{ "p": "payload" }],
70
+ "repeat": "",
71
+ "crontab": "",
72
+ "once": false,
73
+ "onceDelay": 0.1,
74
+ "topic": "",
75
+ "payload": "",
76
+ "payloadType": "str",
77
+ "x": 180,
78
+ "y": 140,
79
+ "wires": [["fn-delay-series-example"]]
80
+ },
81
+ {
82
+ "id": "fn-delay-series-example",
83
+ "type": "function",
84
+ "z": "flow-bullmq-features",
85
+ "name": "addBulk with delays",
86
+ "func": "msg.cmd = \"addBulk\";\nmsg.payload = [\n { name: \"delayed-1\", data: { payload: \"first\" }, opts: { delay: 10000, removeOnComplete: true } },\n { name: \"delayed-2\", data: { payload: \"second\" }, opts: { delay: 20000, removeOnComplete: true } },\n { name: \"delayed-3\", data: { payload: \"third\" }, opts: { delay: 30000, removeOnComplete: true } }\n];\nreturn msg;",
87
+ "outputs": 1,
88
+ "noerr": 0,
89
+ "initialize": "",
90
+ "finalize": "",
91
+ "libs": [],
92
+ "x": 420,
93
+ "y": 140,
94
+ "wires": [["cmd-feature-examples"]]
95
+ },
96
+ {
97
+ "id": "inject-delay-datetime-example",
98
+ "type": "inject",
99
+ "z": "flow-bullmq-features",
100
+ "name": "delay: series at exact date-times",
101
+ "props": [{ "p": "payload" }],
102
+ "repeat": "",
103
+ "crontab": "",
104
+ "once": false,
105
+ "onceDelay": 0.1,
106
+ "topic": "",
107
+ "payload": "",
108
+ "payloadType": "str",
109
+ "x": 190,
110
+ "y": 160,
111
+ "wires": [["fn-delay-datetime-example"]]
112
+ },
113
+ {
114
+ "id": "fn-delay-datetime-example",
115
+ "type": "function",
116
+ "z": "flow-bullmq-features",
117
+ "name": "ISO times to delays",
118
+ "func": "const schedule = [\n { at: \"2030-01-01T09:00:00+11:00\", payload: \"first\" },\n { at: \"2030-01-01T09:15:00+11:00\", payload: \"second\" },\n { at: \"2030-01-01T09:30:00+11:00\", payload: \"third\" }\n];\nconst now = Date.now();\nmsg.cmd = \"addBulk\";\nmsg.payload = schedule.map(({ at, payload }, index) => ({\n name: `scheduled-${index + 1}`,\n data: { payload, scheduledFor: at },\n opts: { delay: Math.max(0, Date.parse(at) - now), removeOnComplete: true }\n}));\nreturn msg;",
119
+ "outputs": 1,
120
+ "noerr": 0,
121
+ "initialize": "",
122
+ "finalize": "",
123
+ "libs": [],
124
+ "x": 420,
125
+ "y": 160,
126
+ "wires": [["cmd-feature-examples"]]
127
+ },
60
128
  {
61
129
  "id": "inject-priority-example",
62
130
  "type": "inject",
63
131
  "z": "flow-bullmq-features",
64
132
  "name": "priority: high priority",
65
- "props": [{ "p": "payload" }],
133
+ "props": [
134
+ {
135
+ "p": "payload"
136
+ }
137
+ ],
66
138
  "repeat": "",
67
139
  "crontab": "",
68
140
  "once": false,
@@ -94,7 +166,11 @@
94
166
  "type": "inject",
95
167
  "z": "flow-bullmq-features",
96
168
  "name": "dedupe: same job once",
97
- "props": [{ "p": "payload" }],
169
+ "props": [
170
+ {
171
+ "p": "payload"
172
+ }
173
+ ],
98
174
  "repeat": "",
99
175
  "crontab": "",
100
176
  "once": false,
@@ -126,7 +202,11 @@
126
202
  "type": "inject",
127
203
  "z": "flow-bullmq-features",
128
204
  "name": "rate limit: 2 per second",
129
- "props": [{ "p": "payload" }],
205
+ "props": [
206
+ {
207
+ "p": "payload"
208
+ }
209
+ ],
130
210
  "repeat": "",
131
211
  "crontab": "",
132
212
  "once": false,
@@ -158,7 +238,11 @@
158
238
  "type": "inject",
159
239
  "z": "flow-bullmq-features",
160
240
  "name": "scheduler: every minute",
161
- "props": [{ "p": "payload" }],
241
+ "props": [
242
+ {
243
+ "p": "payload"
244
+ }
245
+ ],
162
246
  "repeat": "",
163
247
  "crontab": "",
164
248
  "once": false,
@@ -174,8 +258,8 @@
174
258
  "id": "fn-scheduler-example",
175
259
  "type": "function",
176
260
  "z": "flow-bullmq-features",
177
- "name": "repeat.pattern",
178
- "func": "msg.cmd = \"add\";\nmsg.jobName = \"heartbeat\";\nmsg.jobopts = {\n jobId: \"heartbeat-every-minute\",\n repeat: { pattern: \"*/1 * * * *\" },\n removeOnComplete: true\n};\nreturn msg;",
261
+ "name": "upsertJobScheduler",
262
+ "func": "msg.cmd = \"upsertJobScheduler\";\nmsg.schedulerId = \"heartbeat-every-minute\";\nmsg.repeat = { pattern: \"*/1 * * * *\" };\nmsg.template = {\n name: \"heartbeat\",\n data: { payload: msg.payload },\n opts: { removeOnComplete: true }\n};\nreturn msg;",
179
263
  "outputs": 1,
180
264
  "noerr": 0,
181
265
  "initialize": "",
@@ -187,7 +271,7 @@
187
271
  },
188
272
  {
189
273
  "id": "cmd-feature-examples",
190
- "type": "bull cmd",
274
+ "type": "bullmq cmd",
191
275
  "z": "flow-bullmq-features",
192
276
  "name": "send command",
193
277
  "queue": "queue-bullmq-features",
@@ -197,7 +281,7 @@
197
281
  },
198
282
  {
199
283
  "id": "run-immediate-example",
200
- "type": "bull run",
284
+ "type": "bullmq run",
201
285
  "z": "flow-bullmq-features",
202
286
  "name": "worker: immediate complete",
203
287
  "queue": "queue-bullmq-features",
@@ -212,7 +296,7 @@
212
296
  },
213
297
  {
214
298
  "id": "run-manual-example",
215
- "type": "bull run",
299
+ "type": "bullmq run",
216
300
  "z": "flow-bullmq-features",
217
301
  "name": "manual ack worker",
218
302
  "queue": "queue-bullmq-features",
@@ -227,7 +311,7 @@
227
311
  },
228
312
  {
229
313
  "id": "job-progress-example",
230
- "type": "bull job",
314
+ "type": "bullmq job",
231
315
  "z": "flow-bullmq-features",
232
316
  "name": "progress 50%",
233
317
  "action": "progress",
@@ -237,7 +321,7 @@
237
321
  },
238
322
  {
239
323
  "id": "job-complete-example",
240
- "type": "bull job",
324
+ "type": "bullmq job",
241
325
  "z": "flow-bullmq-features",
242
326
  "name": "complete job",
243
327
  "action": "complete",
@@ -245,9 +329,55 @@
245
329
  "y": 620,
246
330
  "wires": [["debug-worker-output"]]
247
331
  },
332
+ {
333
+ "id": "job-cancel-example",
334
+ "type": "bullmq job",
335
+ "z": "flow-bullmq-features",
336
+ "name": "cancel: stop running job",
337
+ "action": "cancelJob",
338
+ "x": 450,
339
+ "y": 920,
340
+ "wires": [["debug-worker-output"]]
341
+ },
342
+ {
343
+ "id": "inject-metrics-example",
344
+ "type": "inject",
345
+ "z": "flow-bullmq-features",
346
+ "name": "metrics: exportPrometheusMetrics",
347
+ "props": [
348
+ {
349
+ "p": "payload"
350
+ }
351
+ ],
352
+ "repeat": "",
353
+ "crontab": "",
354
+ "once": false,
355
+ "onceDelay": 0.1,
356
+ "topic": "",
357
+ "payload": "",
358
+ "payloadType": "str",
359
+ "x": 200,
360
+ "y": 1000,
361
+ "wires": [["fn-metrics-example"]]
362
+ },
363
+ {
364
+ "id": "fn-metrics-example",
365
+ "type": "function",
366
+ "z": "flow-bullmq-features",
367
+ "name": "exportPrometheusMetrics",
368
+ "func": "msg.cmd = \"exportPrometheusMetrics\";\nreturn msg;",
369
+ "outputs": 1,
370
+ "noerr": 0,
371
+ "initialize": "",
372
+ "finalize": "",
373
+ "libs": [],
374
+ "x": 460,
375
+ "y": 1000,
376
+ "wires": [["cmd-feature-examples"]]
377
+ },
248
378
  {
249
379
  "id": "events-feature-example",
250
- "type": "bull events",
380
+ "type": "bullmq events",
251
381
  "z": "flow-bullmq-features",
252
382
  "name": "events: completed failed delayed deduped",
253
383
  "queue": "queue-bullmq-features",
@@ -261,7 +391,11 @@
261
391
  "type": "inject",
262
392
  "z": "flow-bullmq-features",
263
393
  "name": "flow: parent plus child",
264
- "props": [{ "p": "payload" }],
394
+ "props": [
395
+ {
396
+ "p": "payload"
397
+ }
398
+ ],
265
399
  "repeat": "",
266
400
  "crontab": "",
267
401
  "once": false,
@@ -275,7 +409,7 @@
275
409
  },
276
410
  {
277
411
  "id": "flow-feature-example",
278
- "type": "bull flow",
412
+ "type": "bullmq flow",
279
413
  "z": "flow-bullmq-features",
280
414
  "name": "add parent/child flow",
281
415
  "queue": "queue-bullmq-features",
@@ -327,5 +461,73 @@
327
461
  "x": 900,
328
462
  "y": 720,
329
463
  "wires": []
464
+ },
465
+ {
466
+ "id": "queue-bullmq-cancel",
467
+ "type": "bullmq-queue-server",
468
+ "name": "bullmq-cancel",
469
+ "deployment": "single",
470
+ "address": "localhost",
471
+ "port": "6379",
472
+ "db": "",
473
+ "clusterNodes": "",
474
+ "sentinels": "",
475
+ "sentinelMasterName": "",
476
+ "username": "",
477
+ "sentinelUsername": "",
478
+ "tls": false,
479
+ "sentinelTls": false,
480
+ "tlsRejectUnauthorized": true,
481
+ "tlsServerName": "",
482
+ "prefix": ""
483
+ },
484
+ {
485
+ "id": "inject-cancel-example",
486
+ "type": "inject",
487
+ "z": "flow-bullmq-features",
488
+ "name": "cancel: stop running job",
489
+ "props": [
490
+ {
491
+ "p": "payload"
492
+ }
493
+ ],
494
+ "payload": "this job gets cancelled",
495
+ "payloadType": "str",
496
+ "x": 160,
497
+ "y": 860,
498
+ "wires": [["fn-cancel-example"]]
499
+ },
500
+ {
501
+ "id": "fn-cancel-example",
502
+ "type": "function",
503
+ "z": "flow-bullmq-features",
504
+ "name": "add to the cancel queue",
505
+ "func": "msg.cmd = \"add\";\nmsg.jobName = \"cancellable\";\nmsg.jobopts = {\n attempts: 1,\n removeOnFail: false\n};\nreturn msg;",
506
+ "x": 410,
507
+ "y": 860,
508
+ "wires": [["cmd-cancel-example"]]
509
+ },
510
+ {
511
+ "id": "cmd-cancel-example",
512
+ "type": "bullmq cmd",
513
+ "z": "flow-bullmq-features",
514
+ "name": "cmd: cancel queue",
515
+ "queue": "queue-bullmq-cancel",
516
+ "x": 680,
517
+ "y": 860,
518
+ "wires": [[]]
519
+ },
520
+ {
521
+ "id": "run-cancel-example",
522
+ "type": "bullmq run",
523
+ "z": "flow-bullmq-features",
524
+ "name": "cancellable worker",
525
+ "queue": "queue-bullmq-cancel",
526
+ "completionMode": "manual",
527
+ "ackTimeout": "300000",
528
+ "concurrency": "1",
529
+ "x": 180,
530
+ "y": 920,
531
+ "wires": [["job-cancel-example"]]
330
532
  }
331
533
  ]
@@ -8,7 +8,7 @@
8
8
  },
9
9
  {
10
10
  "id": "queue-basecasts",
11
- "type": "bull-queue-server",
11
+ "type": "bullmq-queue-server",
12
12
  "name": "basecasts",
13
13
  "deployment": "single",
14
14
  "address": "localhost",
@@ -59,7 +59,7 @@
59
59
  },
60
60
  {
61
61
  "id": "cmd-simple",
62
- "type": "bull cmd",
62
+ "type": "bullmq cmd",
63
63
  "z": "flow-basecasts",
64
64
  "name": "add simple",
65
65
  "queue": "queue-basecasts",
@@ -69,7 +69,7 @@
69
69
  },
70
70
  {
71
71
  "id": "run-immediate",
72
- "type": "bull run",
72
+ "type": "bullmq run",
73
73
  "z": "flow-basecasts",
74
74
  "name": "run immediate",
75
75
  "queue": "queue-basecasts",
@@ -103,8 +103,8 @@
103
103
  "id": "fn-required-schedule",
104
104
  "type": "function",
105
105
  "z": "flow-basecasts",
106
- "name": "add required repeat cron",
107
- "func": "msg.cmd = \"add\";\nmsg.jobopts = {\n jobId: msg.payload,\n removeOnComplete: true,\n repeat: {\n cron: \"30 9,19,29,39,49,59 * * * *\"\n }\n};\nreturn msg;",
106
+ "name": "upsert job scheduler",
107
+ "func": "msg.cmd = \"upsertJobScheduler\";\nmsg.schedulerId = msg.payload;\nmsg.repeat = {\n pattern: \"30 9,19,29,39,49,59 * * * *\",\n tz: \"UTC\"\n};\nmsg.template = {\n name: \"default\",\n data: { payload: msg.payload },\n opts: { removeOnComplete: true }\n};\nreturn msg;",
108
108
  "outputs": 1,
109
109
  "noerr": 0,
110
110
  "initialize": "",
@@ -116,7 +116,7 @@
116
116
  },
117
117
  {
118
118
  "id": "cmd-required-schedule",
119
- "type": "bull cmd",
119
+ "type": "bullmq cmd",
120
120
  "z": "flow-basecasts",
121
121
  "name": "upsert scheduler",
122
122
  "queue": "queue-basecasts",
@@ -158,7 +158,7 @@
158
158
  },
159
159
  {
160
160
  "id": "cmd-delayed-priority",
161
- "type": "bull cmd",
161
+ "type": "bullmq cmd",
162
162
  "z": "flow-basecasts",
163
163
  "name": "add delayed priority",
164
164
  "queue": "queue-basecasts",
@@ -168,7 +168,7 @@
168
168
  },
169
169
  {
170
170
  "id": "events-basecasts",
171
- "type": "bull events",
171
+ "type": "bullmq events",
172
172
  "z": "flow-basecasts",
173
173
  "name": "events",
174
174
  "queue": "queue-basecasts",
@@ -179,7 +179,7 @@
179
179
  },
180
180
  {
181
181
  "id": "run-manual",
182
- "type": "bull run",
182
+ "type": "bullmq run",
183
183
  "z": "flow-basecasts",
184
184
  "name": "run manual",
185
185
  "queue": "queue-basecasts",
@@ -194,7 +194,7 @@
194
194
  },
195
195
  {
196
196
  "id": "job-complete",
197
- "type": "bull job",
197
+ "type": "bullmq job",
198
198
  "z": "flow-basecasts",
199
199
  "name": "complete manual job",
200
200
  "action": "complete",
@@ -221,7 +221,7 @@
221
221
  },
222
222
  {
223
223
  "id": "flow-producer",
224
- "type": "bull flow",
224
+ "type": "bullmq flow",
225
225
  "z": "flow-basecasts",
226
226
  "name": "add flow",
227
227
  "queue": "queue-basecasts",
@@ -0,0 +1,149 @@
1
+ [
2
+ {
3
+ "id": "flow-postgres-backend",
4
+ "type": "tab",
5
+ "label": "PostgreSQL backend",
6
+ "disabled": false,
7
+ "info": ""
8
+ },
9
+ {
10
+ "id": "queue-postgres-backend",
11
+ "type": "bullmq-queue-server",
12
+ "name": "pgcasts",
13
+ "backend": "postgres",
14
+ "address": "localhost",
15
+ "port": "5432",
16
+ "database": "bullmq",
17
+ "username": "bullmq",
18
+ "schema": "",
19
+ "max": "",
20
+ "migrate": true,
21
+ "tls": false,
22
+ "tlsRejectUnauthorized": true,
23
+ "tlsServerName": "",
24
+ "removeOnComplete": "1000",
25
+ "removeOnFail": "5000",
26
+ "deployment": "single",
27
+ "db": "",
28
+ "clusterNodes": "",
29
+ "sentinels": "",
30
+ "sentinelMasterName": "",
31
+ "sentinelUsername": "",
32
+ "sentinelTls": false,
33
+ "prefix": "",
34
+ "telemetry": false,
35
+ "telemetryServiceName": "",
36
+ "telemetryMetrics": false
37
+ },
38
+ {
39
+ "id": "inject-postgres-add",
40
+ "type": "inject",
41
+ "z": "flow-postgres-backend",
42
+ "name": "postgres: add a job",
43
+ "props": [
44
+ {
45
+ "p": "payload"
46
+ }
47
+ ],
48
+ "repeat": "",
49
+ "crontab": "",
50
+ "once": false,
51
+ "onceDelay": 0.1,
52
+ "topic": "",
53
+ "payload": "order-1",
54
+ "payloadType": "str",
55
+ "x": 180,
56
+ "y": 120,
57
+ "wires": [["fn-postgres-add"]]
58
+ },
59
+ {
60
+ "id": "fn-postgres-add",
61
+ "type": "function",
62
+ "z": "flow-postgres-backend",
63
+ "name": "add order job",
64
+ "func": "// Nothing here is PostgreSQL-specific: the same msg.cmd values, job options\n// and worker messages work on either backend. Only the queue config node\n// differs, which is the point of this example.\nmsg.cmd = \"add\";\nmsg.payload = { orderId: msg.payload || \"order-1\", stage: \"received\" };\nmsg.jobopts = { removeOnComplete: 1000, removeOnFail: 5000 };\nreturn msg;",
65
+ "outputs": 1,
66
+ "noerr": 0,
67
+ "initialize": "",
68
+ "finalize": "",
69
+ "libs": [],
70
+ "x": 420,
71
+ "y": 120,
72
+ "wires": [["cmd-postgres-backend"]]
73
+ },
74
+ {
75
+ "id": "cmd-postgres-backend",
76
+ "type": "bullmq cmd",
77
+ "z": "flow-postgres-backend",
78
+ "name": "queue command",
79
+ "queue": "queue-postgres-backend",
80
+ "x": 680,
81
+ "y": 120,
82
+ "wires": [["debug-postgres-command"]]
83
+ },
84
+ {
85
+ "id": "debug-postgres-command",
86
+ "type": "debug",
87
+ "z": "flow-postgres-backend",
88
+ "name": "command output",
89
+ "active": true,
90
+ "tosidebar": true,
91
+ "console": false,
92
+ "tostatus": false,
93
+ "complete": "payload",
94
+ "targetType": "msg",
95
+ "statusVal": "",
96
+ "statusType": "auto",
97
+ "x": 900,
98
+ "y": 120,
99
+ "wires": []
100
+ },
101
+ {
102
+ "id": "run-postgres-backend",
103
+ "type": "bullmq run",
104
+ "z": "flow-postgres-backend",
105
+ "name": "order worker",
106
+ "queue": "queue-postgres-backend",
107
+ "completionMode": "immediate",
108
+ "ackTimeout": 300000,
109
+ "concurrency": 1,
110
+ "maxStartedAttempts": 100,
111
+ "limiterMax": "",
112
+ "limiterDuration": "",
113
+ "x": 180,
114
+ "y": 260,
115
+ "wires": [["fn-postgres-worker"]]
116
+ },
117
+ {
118
+ "id": "fn-postgres-worker",
119
+ "type": "function",
120
+ "z": "flow-postgres-backend",
121
+ "name": "handle order",
122
+ "func": "// The worker receives the job's data as msg.payload, exactly as it does on\n// Redis.\nmsg.topic = msg.payload.stage;\nreturn msg;",
123
+ "outputs": 1,
124
+ "noerr": 0,
125
+ "initialize": "",
126
+ "finalize": "",
127
+ "libs": [],
128
+ "x": 420,
129
+ "y": 260,
130
+ "wires": [["debug-postgres-worker"]]
131
+ },
132
+ {
133
+ "id": "debug-postgres-worker",
134
+ "type": "debug",
135
+ "z": "flow-postgres-backend",
136
+ "name": "processed order",
137
+ "active": true,
138
+ "tosidebar": true,
139
+ "console": false,
140
+ "tostatus": true,
141
+ "complete": "payload",
142
+ "targetType": "msg",
143
+ "statusVal": "topic",
144
+ "statusType": "msg",
145
+ "x": 660,
146
+ "y": 260,
147
+ "wires": []
148
+ }
149
+ ]