pg-boss 7.4.0 → 8.1.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.
- package/README.md +1 -1
- package/package.json +12 -9
- package/src/attorney.js +1 -1
- package/src/index.js +3 -1
- package/src/manager.js +34 -26
- package/src/plans.js +1 -0
- package/src/timekeeper.js +2 -1
- package/types.d.ts +22 -15
package/README.md
CHANGED
|
@@ -50,7 +50,7 @@ This will likely cater the most to teams already familiar with the simplicity of
|
|
|
50
50
|
* Automatic maintenance operations to manage table growth
|
|
51
51
|
|
|
52
52
|
## Requirements
|
|
53
|
-
* Node
|
|
53
|
+
* Node 14 or higher
|
|
54
54
|
* PostgreSQL 9.5 or higher
|
|
55
55
|
|
|
56
56
|
## Installation
|
package/package.json
CHANGED
|
@@ -1,31 +1,34 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pg-boss",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "8.1.0",
|
|
4
4
|
"description": "Queueing jobs in Node.js using PostgreSQL like a boss",
|
|
5
5
|
"main": "./src/index.js",
|
|
6
6
|
"engines": {
|
|
7
|
-
"node": ">=
|
|
7
|
+
"node": ">=14"
|
|
8
8
|
},
|
|
9
9
|
"dependencies": {
|
|
10
10
|
"cron-parser": "^4.0.0",
|
|
11
11
|
"delay": "^5.0.0",
|
|
12
12
|
"lodash.debounce": "^4.0.8",
|
|
13
|
-
"p-map": "^
|
|
13
|
+
"p-map": "^5.3.0",
|
|
14
14
|
"pg": "^8.5.1",
|
|
15
|
-
"
|
|
15
|
+
"serialize-error": "^11.0.0",
|
|
16
|
+
"uuid": "^9.0.0"
|
|
16
17
|
},
|
|
17
18
|
"devDependencies": {
|
|
18
|
-
"@types/node": "^
|
|
19
|
+
"@types/node": "^18.0.0",
|
|
19
20
|
"coveralls": "^3.1.0",
|
|
20
|
-
"luxon": "^
|
|
21
|
-
"mocha": "^
|
|
21
|
+
"luxon": "^3.0.1",
|
|
22
|
+
"mocha": "^10.0.0",
|
|
22
23
|
"nyc": "^15.1.0",
|
|
23
|
-
"standard": "^
|
|
24
|
+
"standard": "^17.0.0"
|
|
24
25
|
},
|
|
25
26
|
"scripts": {
|
|
26
27
|
"test": "standard && mocha",
|
|
27
28
|
"cover": "nyc --reporter=text npm test",
|
|
28
|
-
"
|
|
29
|
+
"travis-cover": "nyc --reporter=text npm run travis-test",
|
|
30
|
+
"travis-test": "standard && mocha --jobs 0 --exit",
|
|
31
|
+
"forcover": "npm run travis-cover && nyc report --reporter=text-lcov | coveralls",
|
|
29
32
|
"export-schema": "node ./scripts/construct.js",
|
|
30
33
|
"export-migration": "node ./scripts/migrate.js",
|
|
31
34
|
"export-rollback": "node ./scripts/rollback.js",
|
package/src/attorney.js
CHANGED
|
@@ -377,7 +377,7 @@ function applyMonitoringConfig (config) {
|
|
|
377
377
|
|
|
378
378
|
function applyUuidConfig (config) {
|
|
379
379
|
assert(!('uuid' in config) || config.uuid === 'v1' || config.uuid === 'v4', 'configuration assert: uuid option only supports v1 or v4')
|
|
380
|
-
config.uuid = config.uuid || '
|
|
380
|
+
config.uuid = config.uuid || 'v4'
|
|
381
381
|
}
|
|
382
382
|
|
|
383
383
|
function warnClockSkew (message) {
|
package/src/index.js
CHANGED
|
@@ -90,6 +90,8 @@ class PgBoss extends EventEmitter {
|
|
|
90
90
|
}
|
|
91
91
|
|
|
92
92
|
async start () {
|
|
93
|
+
const { serializeError } = await import('serialize-error')
|
|
94
|
+
|
|
93
95
|
if (!this.stopped) {
|
|
94
96
|
return this
|
|
95
97
|
}
|
|
@@ -104,7 +106,7 @@ class PgBoss extends EventEmitter {
|
|
|
104
106
|
|
|
105
107
|
this.started = true
|
|
106
108
|
|
|
107
|
-
this.manager.start()
|
|
109
|
+
this.manager.start({ stringify: serializeError })
|
|
108
110
|
|
|
109
111
|
if (!this.config.noSupervisor) {
|
|
110
112
|
await this.boss.supervise()
|
package/src/manager.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
const assert = require('assert')
|
|
2
2
|
const EventEmitter = require('events')
|
|
3
|
-
const pMap = require('p-map')
|
|
4
3
|
const delay = require('delay')
|
|
5
4
|
const uuid = require('uuid')
|
|
6
5
|
const debounce = require('lodash.debounce')
|
|
@@ -45,6 +44,8 @@ class Manager extends EventEmitter {
|
|
|
45
44
|
constructor (db, config) {
|
|
46
45
|
super()
|
|
47
46
|
|
|
47
|
+
this.stringify = null
|
|
48
|
+
|
|
48
49
|
this.config = config
|
|
49
50
|
this.db = db
|
|
50
51
|
|
|
@@ -97,7 +98,8 @@ class Manager extends EventEmitter {
|
|
|
97
98
|
this.emitWipThrottled = debounce(() => this.emit(events.wip, this.getWipData()), WIP_EVENT_INTERVAL, WIP_DEBOUNCE_OPTIONS)
|
|
98
99
|
}
|
|
99
100
|
|
|
100
|
-
start () {
|
|
101
|
+
start ({ stringify }) {
|
|
102
|
+
this.stringify = stringify
|
|
101
103
|
this.stopping = false
|
|
102
104
|
}
|
|
103
105
|
|
|
@@ -211,6 +213,8 @@ class Manager extends EventEmitter {
|
|
|
211
213
|
const fetch = () => this.fetch(name, batchSize || (teamSize - queueSize), { includeMetadata })
|
|
212
214
|
|
|
213
215
|
const onFetch = async (jobs) => {
|
|
216
|
+
const { default: pMap } = await import('p-map')
|
|
217
|
+
|
|
214
218
|
if (this.config.__test__throw_worker) {
|
|
215
219
|
throw new Error('__test__throw_worker')
|
|
216
220
|
}
|
|
@@ -393,6 +397,7 @@ class Manager extends EventEmitter {
|
|
|
393
397
|
|
|
394
398
|
async createJob (name, data, options, singletonOffset = 0) {
|
|
395
399
|
const {
|
|
400
|
+
db: wrapper,
|
|
396
401
|
expireIn,
|
|
397
402
|
priority,
|
|
398
403
|
startAfter,
|
|
@@ -423,8 +428,8 @@ class Manager extends EventEmitter {
|
|
|
423
428
|
keepUntil, // 13
|
|
424
429
|
onComplete // 14
|
|
425
430
|
]
|
|
426
|
-
|
|
427
|
-
const result = await
|
|
431
|
+
const db = wrapper || this.db
|
|
432
|
+
const result = await db.executeSql(this.insertJobCommand, values)
|
|
428
433
|
|
|
429
434
|
if (result && result.rowCount === 1) {
|
|
430
435
|
return result.rows[0].id
|
|
@@ -445,10 +450,12 @@ class Manager extends EventEmitter {
|
|
|
445
450
|
return await this.createJob(name, data, options, singletonOffset)
|
|
446
451
|
}
|
|
447
452
|
|
|
448
|
-
async insert (jobs) {
|
|
453
|
+
async insert (jobs, options = {}) {
|
|
454
|
+
const { db: wrapper } = options
|
|
455
|
+
const db = wrapper || this.db
|
|
449
456
|
const checkedJobs = Attorney.checkInsertArgs(jobs)
|
|
450
457
|
const data = JSON.stringify(checkedJobs)
|
|
451
|
-
return await
|
|
458
|
+
return await db.executeSql(this.insertJobsCommand, [data])
|
|
452
459
|
}
|
|
453
460
|
|
|
454
461
|
getDebounceStartAfter (singletonSeconds, clockOffset) {
|
|
@@ -470,8 +477,8 @@ class Manager extends EventEmitter {
|
|
|
470
477
|
|
|
471
478
|
async fetch (name, batchSize, options = {}) {
|
|
472
479
|
const values = Attorney.checkFetchArgs(name, batchSize, options)
|
|
473
|
-
|
|
474
|
-
const result = await
|
|
480
|
+
const db = options.db || this.db
|
|
481
|
+
const result = await db.executeSql(
|
|
475
482
|
this.nextJobCommand(options.includeMetadata || false),
|
|
476
483
|
[values.name, batchSize || 1]
|
|
477
484
|
)
|
|
@@ -513,15 +520,11 @@ class Manager extends EventEmitter {
|
|
|
513
520
|
mapCompletionDataArg (data) {
|
|
514
521
|
if (data === null || typeof data === 'undefined' || typeof data === 'function') { return null }
|
|
515
522
|
|
|
516
|
-
|
|
517
|
-
const newData = {}
|
|
518
|
-
Object.getOwnPropertyNames(data).forEach(key => { newData[key] = data[key] })
|
|
519
|
-
data = newData
|
|
520
|
-
}
|
|
521
|
-
|
|
522
|
-
return (typeof data === 'object' && !Array.isArray(data))
|
|
523
|
+
const result = (typeof data === 'object' && !Array.isArray(data))
|
|
523
524
|
? data
|
|
524
525
|
: { value: data }
|
|
526
|
+
|
|
527
|
+
return this.stringify(result)
|
|
525
528
|
}
|
|
526
529
|
|
|
527
530
|
mapCompletionResponse (ids, result) {
|
|
@@ -532,27 +535,31 @@ class Manager extends EventEmitter {
|
|
|
532
535
|
}
|
|
533
536
|
}
|
|
534
537
|
|
|
535
|
-
async complete (id, data) {
|
|
538
|
+
async complete (id, data, options = {}) {
|
|
539
|
+
const db = options.db || this.db
|
|
536
540
|
const ids = this.mapCompletionIdArg(id, 'complete')
|
|
537
|
-
const result = await
|
|
541
|
+
const result = await db.executeSql(this.completeJobsCommand, [ids, this.mapCompletionDataArg(data)])
|
|
538
542
|
return this.mapCompletionResponse(ids, result)
|
|
539
543
|
}
|
|
540
544
|
|
|
541
|
-
async fail (id, data) {
|
|
545
|
+
async fail (id, data, options = {}) {
|
|
546
|
+
const db = options.db || this.db
|
|
542
547
|
const ids = this.mapCompletionIdArg(id, 'fail')
|
|
543
|
-
const result = await
|
|
548
|
+
const result = await db.executeSql(this.failJobsCommand, [ids, this.mapCompletionDataArg(data)])
|
|
544
549
|
return this.mapCompletionResponse(ids, result)
|
|
545
550
|
}
|
|
546
551
|
|
|
547
|
-
async cancel (id) {
|
|
552
|
+
async cancel (id, options = {}) {
|
|
553
|
+
const db = options.db || this.db
|
|
548
554
|
const ids = this.mapCompletionIdArg(id, 'cancel')
|
|
549
|
-
const result = await
|
|
555
|
+
const result = await db.executeSql(this.cancelJobsCommand, [ids])
|
|
550
556
|
return this.mapCompletionResponse(ids, result)
|
|
551
557
|
}
|
|
552
558
|
|
|
553
|
-
async resume (id) {
|
|
559
|
+
async resume (id, options = {}) {
|
|
560
|
+
const db = options.db || this.db
|
|
554
561
|
const ids = this.mapCompletionIdArg(id, 'resume')
|
|
555
|
-
const result = await
|
|
562
|
+
const result = await db.executeSql(this.resumeJobsCommand, [ids])
|
|
556
563
|
return this.mapCompletionResponse(ids, result)
|
|
557
564
|
}
|
|
558
565
|
|
|
@@ -584,14 +591,15 @@ class Manager extends EventEmitter {
|
|
|
584
591
|
return result ? parseFloat(result.rows[0].count) : null
|
|
585
592
|
}
|
|
586
593
|
|
|
587
|
-
async getJobById (id) {
|
|
588
|
-
const
|
|
594
|
+
async getJobById (id, options = {}) {
|
|
595
|
+
const db = options.db || this.db
|
|
596
|
+
const result1 = await db.executeSql(this.getJobByIdCommand, [id])
|
|
589
597
|
|
|
590
598
|
if (result1 && result1.rows && result1.rows.length === 1) {
|
|
591
599
|
return result1.rows[0]
|
|
592
600
|
}
|
|
593
601
|
|
|
594
|
-
const result2 = await
|
|
602
|
+
const result2 = await db.executeSql(this.getArchivedJobByIdCommand, [id])
|
|
595
603
|
|
|
596
604
|
if (result2 && result2.rows && result2.rows.length === 1) {
|
|
597
605
|
return result2.rows[0]
|
package/src/plans.js
CHANGED
package/src/timekeeper.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
const pMap = require('p-map')
|
|
2
1
|
const EventEmitter = require('events')
|
|
3
2
|
const plans = require('./plans')
|
|
4
3
|
const cronParser = require('cron-parser')
|
|
@@ -126,6 +125,8 @@ class Timekeeper extends EventEmitter {
|
|
|
126
125
|
async onCron () {
|
|
127
126
|
if (this.stopped) return
|
|
128
127
|
|
|
128
|
+
const { default: pMap } = await import('p-map')
|
|
129
|
+
|
|
129
130
|
try {
|
|
130
131
|
if (this.config.__test__throw_clock_monitoring) {
|
|
131
132
|
throw new Error('clock monitoring error')
|
package/types.d.ts
CHANGED
|
@@ -91,7 +91,13 @@ declare namespace PgBoss {
|
|
|
91
91
|
singletonNextSlot?: boolean;
|
|
92
92
|
}
|
|
93
93
|
|
|
94
|
-
|
|
94
|
+
interface ConnectionOptions {
|
|
95
|
+
db?: Db;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
type InsertOptions = ConnectionOptions;
|
|
99
|
+
|
|
100
|
+
type SendOptions = JobOptions & ExpirationOptions & RetentionOptions & RetryOptions & CompletionOptions & ConnectionOptions;
|
|
95
101
|
|
|
96
102
|
type ScheduleOptions = SendOptions & { tz?: string }
|
|
97
103
|
|
|
@@ -112,7 +118,7 @@ declare namespace PgBoss {
|
|
|
112
118
|
|
|
113
119
|
type FetchOptions = {
|
|
114
120
|
includeMetadata?: boolean;
|
|
115
|
-
}
|
|
121
|
+
} & ConnectionOptions;
|
|
116
122
|
|
|
117
123
|
interface WorkHandler<ReqData, ResData> {
|
|
118
124
|
(job: PgBoss.JobWithDoneCallback<ReqData, ResData>): Promise<ResData> | void;
|
|
@@ -190,7 +196,7 @@ declare namespace PgBoss {
|
|
|
190
196
|
retryLimit?: number;
|
|
191
197
|
retryDelay?: number;
|
|
192
198
|
retryBackoff?: boolean;
|
|
193
|
-
startAfter?: Date | string;
|
|
199
|
+
startAfter?: Date | string;
|
|
194
200
|
singletonKey?: string;
|
|
195
201
|
expireInSeconds?: number;
|
|
196
202
|
keepUntil?: Date | string;
|
|
@@ -298,6 +304,7 @@ declare class PgBoss extends EventEmitter {
|
|
|
298
304
|
sendDebounced(name: string, data: object, options: PgBoss.SendOptions, seconds: number, key: string): Promise<string | null>;
|
|
299
305
|
|
|
300
306
|
insert(jobs: PgBoss.JobInsert[]): Promise<void>;
|
|
307
|
+
insert(jobs: PgBoss.JobInsert[], options: PgBoss.InsertOptions): Promise<void>;
|
|
301
308
|
|
|
302
309
|
work<ReqData, ResData>(name: string, handler: PgBoss.WorkHandler<ReqData, ResData>): Promise<string>;
|
|
303
310
|
work<ReqData, ResData>(name: string, options: PgBoss.WorkOptions & { includeMetadata: true }, handler: PgBoss.WorkWithMetadataHandler<ReqData, ResData>): Promise<string>;
|
|
@@ -311,7 +318,7 @@ declare class PgBoss extends EventEmitter {
|
|
|
311
318
|
|
|
312
319
|
/**
|
|
313
320
|
* Notify worker that something has changed
|
|
314
|
-
* @param workerId
|
|
321
|
+
* @param workerId
|
|
315
322
|
*/
|
|
316
323
|
notifyWorker(workerId: string): void;
|
|
317
324
|
|
|
@@ -334,22 +341,22 @@ declare class PgBoss extends EventEmitter {
|
|
|
334
341
|
fetchCompleted<T>(name: string, batchSize: number, options: PgBoss.FetchOptions & { includeMetadata: true }): Promise<PgBoss.JobWithMetadata<T>[] | null>;
|
|
335
342
|
fetchCompleted<T>(name: string, batchSize: number, options: PgBoss.FetchOptions): Promise<PgBoss.Job<T>[] | null>;
|
|
336
343
|
|
|
337
|
-
cancel(id: string): Promise<void>;
|
|
338
|
-
cancel(ids: string[]): Promise<void>;
|
|
344
|
+
cancel(id: string, options: PgBoss.ConnectionOptions): Promise<void>;
|
|
345
|
+
cancel(ids: string[], options: PgBoss.ConnectionOptions): Promise<void>;
|
|
339
346
|
|
|
340
|
-
resume(id: string): Promise<void>;
|
|
341
|
-
resume(ids: string[]): Promise<void>;
|
|
347
|
+
resume(id: string, options: PgBoss.ConnectionOptions): Promise<void>;
|
|
348
|
+
resume(ids: string[], options: PgBoss.ConnectionOptions): Promise<void>;
|
|
342
349
|
|
|
343
|
-
complete(id: string): Promise<void>;
|
|
344
|
-
complete(id: string, data: object): Promise<void>;
|
|
345
|
-
complete(ids: string[]): Promise<void>;
|
|
350
|
+
complete(id: string, options: PgBoss.ConnectionOptions): Promise<void>;
|
|
351
|
+
complete(id: string, data: object, options: PgBoss.ConnectionOptions): Promise<void>;
|
|
352
|
+
complete(ids: string[], options: PgBoss.ConnectionOptions): Promise<void>;
|
|
346
353
|
|
|
347
|
-
fail(id: string): Promise<void>;
|
|
348
|
-
fail(id: string, data: object): Promise<void>;
|
|
349
|
-
fail(ids: string[]): Promise<void>;
|
|
354
|
+
fail(id: string, options: PgBoss.ConnectionOptions): Promise<void>;
|
|
355
|
+
fail(id: string, data: object, options: PgBoss.ConnectionOptions): Promise<void>;
|
|
356
|
+
fail(ids: string[], options: PgBoss.ConnectionOptions): Promise<void>;
|
|
350
357
|
|
|
351
358
|
getQueueSize(name: string, options?: object): Promise<number>;
|
|
352
|
-
getJobById(id: string): Promise<PgBoss.JobWithMetadata | null>;
|
|
359
|
+
getJobById(id: string, options: PgBoss.ConnectionOptions): Promise<PgBoss.JobWithMetadata | null>;
|
|
353
360
|
|
|
354
361
|
deleteQueue(name: string): Promise<void>;
|
|
355
362
|
deleteAllQueues(): Promise<void>;
|