pg-boss 8.4.0 → 8.4.2
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/package.json +1 -1
- package/src/attorney.js +8 -0
- package/src/boss.js +16 -8
- package/src/manager.js +5 -5
- package/src/timekeeper.js +33 -15
package/package.json
CHANGED
package/src/attorney.js
CHANGED
|
@@ -387,6 +387,14 @@ function applyMonitoringConfig (config) {
|
|
|
387
387
|
('cronMonitorIntervalSeconds' in config)
|
|
388
388
|
? config.cronMonitorIntervalSeconds
|
|
389
389
|
: 60
|
|
390
|
+
|
|
391
|
+
assert(!('cronWorkerIntervalSeconds' in config) || (config.cronWorkerIntervalSeconds >= 1 && config.cronWorkerIntervalSeconds <= 60),
|
|
392
|
+
'configuration assert: cronWorkerIntervalSeconds must be between 1 and 60 seconds')
|
|
393
|
+
|
|
394
|
+
config.cronWorkerIntervalSeconds =
|
|
395
|
+
('cronWorkerIntervalSeconds' in config)
|
|
396
|
+
? config.cronWorkerIntervalSeconds
|
|
397
|
+
: 4
|
|
390
398
|
}
|
|
391
399
|
|
|
392
400
|
function applyUuidConfig (config) {
|
package/src/boss.js
CHANGED
|
@@ -78,11 +78,19 @@ class Boss extends EventEmitter {
|
|
|
78
78
|
|
|
79
79
|
metaMonitor () {
|
|
80
80
|
this.metaMonitorInterval = setInterval(async () => {
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
81
|
+
try {
|
|
82
|
+
if (this.config.__test__throw_meta_monitor) {
|
|
83
|
+
throw new Error(this.config.__test__throw_meta_monitor)
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const { secondsAgo } = await this.getMaintenanceTime()
|
|
87
|
+
|
|
88
|
+
if (secondsAgo > this.maintenanceIntervalSeconds * 2) {
|
|
89
|
+
await this.manager.deleteQueue(queues.MAINTENANCE, { before: states.completed })
|
|
90
|
+
await this.maintenanceAsync()
|
|
91
|
+
}
|
|
92
|
+
} catch (err) {
|
|
93
|
+
this.emit(events.error, err)
|
|
86
94
|
}
|
|
87
95
|
}, this.maintenanceIntervalSeconds * 2 * 1000)
|
|
88
96
|
}
|
|
@@ -116,7 +124,7 @@ class Boss extends EventEmitter {
|
|
|
116
124
|
async onMaintenance (job) {
|
|
117
125
|
try {
|
|
118
126
|
if (this.config.__test__throw_maint) {
|
|
119
|
-
throw new Error(
|
|
127
|
+
throw new Error(this.config.__test__throw_maint)
|
|
120
128
|
}
|
|
121
129
|
|
|
122
130
|
const started = Date.now()
|
|
@@ -143,7 +151,7 @@ class Boss extends EventEmitter {
|
|
|
143
151
|
async onMonitorStates (job) {
|
|
144
152
|
try {
|
|
145
153
|
if (this.config.__test__throw_monitor) {
|
|
146
|
-
throw new Error(
|
|
154
|
+
throw new Error(this.config.__test__throw_monitor)
|
|
147
155
|
}
|
|
148
156
|
|
|
149
157
|
const states = await this.countStates()
|
|
@@ -161,7 +169,7 @@ class Boss extends EventEmitter {
|
|
|
161
169
|
|
|
162
170
|
async stop () {
|
|
163
171
|
if (this.config.__test__throw_stop) {
|
|
164
|
-
throw new Error(
|
|
172
|
+
throw new Error(this.config.__test__throw_stop)
|
|
165
173
|
}
|
|
166
174
|
|
|
167
175
|
if (!this.stopped) {
|
package/src/manager.js
CHANGED
|
@@ -341,7 +341,7 @@ class Manager extends EventEmitter {
|
|
|
341
341
|
}
|
|
342
342
|
|
|
343
343
|
async sendOnce (name, data, options, key) {
|
|
344
|
-
options = options
|
|
344
|
+
options = options ? { ...options } : {}
|
|
345
345
|
|
|
346
346
|
options.singletonKey = key || name
|
|
347
347
|
|
|
@@ -351,7 +351,7 @@ class Manager extends EventEmitter {
|
|
|
351
351
|
}
|
|
352
352
|
|
|
353
353
|
async sendSingleton (name, data, options) {
|
|
354
|
-
options = options
|
|
354
|
+
options = options ? { ...options } : {}
|
|
355
355
|
|
|
356
356
|
options.singletonKey = SINGLETON_QUEUE_KEY
|
|
357
357
|
|
|
@@ -361,7 +361,7 @@ class Manager extends EventEmitter {
|
|
|
361
361
|
}
|
|
362
362
|
|
|
363
363
|
async sendAfter (name, data, options, after) {
|
|
364
|
-
options = options
|
|
364
|
+
options = options ? { ...options } : {}
|
|
365
365
|
options.startAfter = after
|
|
366
366
|
|
|
367
367
|
const result = Attorney.checkSendArgs([name, data, options], this.config)
|
|
@@ -370,7 +370,7 @@ class Manager extends EventEmitter {
|
|
|
370
370
|
}
|
|
371
371
|
|
|
372
372
|
async sendThrottled (name, data, options, seconds, key) {
|
|
373
|
-
options = options
|
|
373
|
+
options = options ? { ...options } : {}
|
|
374
374
|
options.singletonSeconds = seconds
|
|
375
375
|
options.singletonNextSlot = false
|
|
376
376
|
options.singletonKey = key
|
|
@@ -381,7 +381,7 @@ class Manager extends EventEmitter {
|
|
|
381
381
|
}
|
|
382
382
|
|
|
383
383
|
async sendDebounced (name, data, options, seconds, key) {
|
|
384
|
-
options = options
|
|
384
|
+
options = options ? { ...options } : {}
|
|
385
385
|
options.singletonSeconds = seconds
|
|
386
386
|
options.singletonNextSlot = true
|
|
387
387
|
options.singletonKey = key
|
package/src/timekeeper.js
CHANGED
|
@@ -52,8 +52,8 @@ class Timekeeper extends EventEmitter {
|
|
|
52
52
|
// cache the clock skew from the db server
|
|
53
53
|
await this.cacheClockSkew()
|
|
54
54
|
|
|
55
|
-
await this.manager.work(queues.CRON, { newJobCheckIntervalSeconds:
|
|
56
|
-
await this.manager.work(queues.SEND_IT, { newJobCheckIntervalSeconds:
|
|
55
|
+
await this.manager.work(queues.CRON, { newJobCheckIntervalSeconds: this.config.cronWorkerIntervalSeconds }, (job) => this.onCron(job))
|
|
56
|
+
await this.manager.work(queues.SEND_IT, { newJobCheckIntervalSeconds: this.config.cronWorkerIntervalSeconds, teamSize: 50, teamConcurrency: 5 }, (job) => this.onSendIt(job))
|
|
57
57
|
|
|
58
58
|
// uses sendDebounced() to enqueue a cron check
|
|
59
59
|
await this.checkSchedulesAsync()
|
|
@@ -88,29 +88,47 @@ class Timekeeper extends EventEmitter {
|
|
|
88
88
|
}
|
|
89
89
|
|
|
90
90
|
async monitorCron () {
|
|
91
|
-
|
|
91
|
+
try {
|
|
92
|
+
if (this.config.__test__force_cron_monitoring_error) {
|
|
93
|
+
throw new Error(this.config.__test__force_cron_monitoring_error)
|
|
94
|
+
}
|
|
92
95
|
|
|
93
|
-
|
|
94
|
-
|
|
96
|
+
const { secondsAgo } = await this.getCronTime()
|
|
97
|
+
|
|
98
|
+
if (secondsAgo > 60) {
|
|
99
|
+
await this.checkSchedulesAsync()
|
|
100
|
+
}
|
|
101
|
+
} catch (err) {
|
|
102
|
+
this.emit(this.events.error, err)
|
|
95
103
|
}
|
|
96
104
|
}
|
|
97
105
|
|
|
98
106
|
async cacheClockSkew () {
|
|
99
|
-
|
|
107
|
+
let skew = 0
|
|
108
|
+
|
|
109
|
+
try {
|
|
110
|
+
if (this.config.__test__force_clock_monitoring_error) {
|
|
111
|
+
throw new Error(this.config.__test__force_clock_monitoring_error)
|
|
112
|
+
}
|
|
100
113
|
|
|
101
|
-
|
|
114
|
+
const { rows } = await this.db.executeSql(this.getTimeCommand)
|
|
102
115
|
|
|
103
|
-
|
|
116
|
+
const local = Date.now()
|
|
104
117
|
|
|
105
|
-
|
|
118
|
+
const dbTime = parseFloat(rows[0].time)
|
|
106
119
|
|
|
107
|
-
|
|
120
|
+
skew = dbTime - local
|
|
108
121
|
|
|
109
|
-
|
|
110
|
-
Attorney.warnClockSkew(`Instance clock is ${skewSeconds}s ${skew > 0 ? 'slower' : 'faster'} than database.`)
|
|
111
|
-
}
|
|
122
|
+
const skewSeconds = Math.abs(skew) / 1000
|
|
112
123
|
|
|
113
|
-
|
|
124
|
+
if (skewSeconds >= 60 || this.config.__test__force_clock_skew_warning) {
|
|
125
|
+
Attorney.warnClockSkew(`Instance clock is ${skewSeconds}s ${skew > 0 ? 'slower' : 'faster'} than database.`)
|
|
126
|
+
}
|
|
127
|
+
} catch (err) {
|
|
128
|
+
this.emit(this.events.error, err)
|
|
129
|
+
} finally {
|
|
130
|
+
this.clockSkew = skew
|
|
131
|
+
}
|
|
114
132
|
}
|
|
115
133
|
|
|
116
134
|
async checkSchedulesAsync () {
|
|
@@ -128,7 +146,7 @@ class Timekeeper extends EventEmitter {
|
|
|
128
146
|
|
|
129
147
|
try {
|
|
130
148
|
if (this.config.__test__throw_clock_monitoring) {
|
|
131
|
-
throw new Error(
|
|
149
|
+
throw new Error(this.config.__test__throw_clock_monitoring)
|
|
132
150
|
}
|
|
133
151
|
|
|
134
152
|
const items = await this.getSchedules()
|