pg-boss 10.3.3 → 11.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.
- package/README.md +3 -3
- package/docker-compose.yaml +1 -1
- package/package.json +3 -3
- package/src/attorney.js +69 -220
- package/src/boss.js +100 -117
- package/src/db.js +3 -0
- package/src/index.js +6 -12
- package/src/manager.js +225 -191
- package/src/migrationStore.js +0 -88
- package/src/plans.js +469 -446
- package/src/timekeeper.js +46 -40
- package/src/tools.js +19 -2
- package/types.d.ts +78 -137
- package/version.json +1 -1
package/README.md
CHANGED
|
@@ -35,7 +35,7 @@ readme()
|
|
|
35
35
|
|
|
36
36
|
pg-boss is a job queue built in Node.js on top of PostgreSQL in order to provide background processing and reliable asynchronous execution to Node.js applications.
|
|
37
37
|
|
|
38
|
-
pg-boss relies on
|
|
38
|
+
pg-boss relies on Postgres's SKIP LOCKED, a feature built specifically for message queues to resolve record locking challenges inherent with relational databases. This provides exactly-once delivery and the safety of guaranteed atomic commits to asynchronous job processing.
|
|
39
39
|
|
|
40
40
|
This will likely cater the most to teams already familiar with the simplicity of relational database semantics and operations (SQL, querying, and backups). It will be especially useful to those already relying on PostgreSQL that want to limit how many systems are required to monitor and support in their architecture.
|
|
41
41
|
|
|
@@ -48,12 +48,12 @@ This will likely cater the most to teams already familiar with the simplicity of
|
|
|
48
48
|
* Queue storage policies to support a variety of rate limiting, debouncing, and concurrency use cases
|
|
49
49
|
* Priority queues, dead letter queues, job deferral, automatic retries with exponential backoff
|
|
50
50
|
* Pub/sub API for fan-out queue relationships
|
|
51
|
-
*
|
|
51
|
+
* SQL support for non-Node.js runtimes for most operations
|
|
52
52
|
* Serverless function compatible
|
|
53
53
|
* Multi-master compatible (for example, in a Kubernetes ReplicaSet)
|
|
54
54
|
|
|
55
55
|
## Requirements
|
|
56
|
-
* Node
|
|
56
|
+
* Node 22 or higher
|
|
57
57
|
* PostgreSQL 13 or higher
|
|
58
58
|
|
|
59
59
|
## Installation
|
package/docker-compose.yaml
CHANGED
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pg-boss",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "11.0.0",
|
|
4
4
|
"description": "Queueing jobs in Postgres from Node.js like a boss",
|
|
5
5
|
"main": "./src/index.js",
|
|
6
6
|
"engines": {
|
|
7
|
-
"node": ">=
|
|
7
|
+
"node": ">=22"
|
|
8
8
|
},
|
|
9
9
|
"dependencies": {
|
|
10
10
|
"cron-parser": "^4.9.0",
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
"serialize-error": "^8.1.0"
|
|
13
13
|
},
|
|
14
14
|
"devDependencies": {
|
|
15
|
-
"@types/node": "^
|
|
15
|
+
"@types/node": "^22",
|
|
16
16
|
"luxon": "^3.7.2",
|
|
17
17
|
"mocha": "^10.8.2",
|
|
18
18
|
"nyc": "^17.1.0",
|
package/src/attorney.js
CHANGED
|
@@ -3,47 +3,33 @@ const { DEFAULT_SCHEMA } = require('./plans')
|
|
|
3
3
|
|
|
4
4
|
const POLICY = {
|
|
5
5
|
MAX_EXPIRATION_HOURS: 24,
|
|
6
|
-
MIN_POLLING_INTERVAL_MS: 500
|
|
6
|
+
MIN_POLLING_INTERVAL_MS: 500,
|
|
7
|
+
MAX_RETENTION_DAYS: 365
|
|
7
8
|
}
|
|
8
9
|
|
|
9
10
|
module.exports = {
|
|
10
11
|
POLICY,
|
|
11
12
|
getConfig,
|
|
12
13
|
checkSendArgs,
|
|
13
|
-
|
|
14
|
+
validateQueueArgs,
|
|
14
15
|
checkWorkArgs,
|
|
15
16
|
checkFetchArgs,
|
|
16
|
-
warnClockSkew,
|
|
17
17
|
assertPostgresObjectName,
|
|
18
|
-
assertQueueName
|
|
18
|
+
assertQueueName,
|
|
19
|
+
assertKey
|
|
19
20
|
}
|
|
20
21
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
code: 'pg-boss-w02'
|
|
25
|
-
},
|
|
26
|
-
CRON_DISABLED: {
|
|
27
|
-
message: 'Archive interval is set less than 60s. Cron processing is disabled.',
|
|
28
|
-
code: 'pg-boss-w03'
|
|
29
|
-
},
|
|
30
|
-
ON_COMPLETE_REMOVED: {
|
|
31
|
-
message: '\'onComplete\' option detected. This option has been removed. Consider deadLetter if needed.',
|
|
32
|
-
code: 'pg-boss-w04'
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
function checkQueueArgs (name, options = {}) {
|
|
37
|
-
assert(!('deadLetter' in options) || (typeof options.deadLetter === 'string'), 'deadLetter must be a string')
|
|
38
|
-
|
|
39
|
-
applyRetryConfig(options)
|
|
40
|
-
applyExpirationConfig(options)
|
|
41
|
-
applyRetentionConfig(options)
|
|
22
|
+
function validateQueueArgs (config = {}) {
|
|
23
|
+
assert(!('deadLetter' in config) || config.deadLetter === null || (typeof config.deadLetter === 'string'), 'deadLetter must be a string')
|
|
24
|
+
assert(!('deadLetter' in config) || config.deadLetter === null || /[\w-]/.test(config.deadLetter), 'deadLetter can only contain alphanumeric characters, underscores, or hyphens')
|
|
42
25
|
|
|
43
|
-
|
|
26
|
+
validateRetryConfig(config)
|
|
27
|
+
validateExpirationConfig(config)
|
|
28
|
+
validateRetentionConfig(config)
|
|
29
|
+
validateDeletionConfig(config)
|
|
44
30
|
}
|
|
45
31
|
|
|
46
|
-
function checkSendArgs (args
|
|
32
|
+
function checkSendArgs (args) {
|
|
47
33
|
let name, data, options
|
|
48
34
|
|
|
49
35
|
if (typeof args[0] === 'string') {
|
|
@@ -75,40 +61,23 @@ function checkSendArgs (args, defaults) {
|
|
|
75
61
|
assert(!('priority' in options) || (Number.isInteger(options.priority)), 'priority must be an integer')
|
|
76
62
|
options.priority = options.priority || 0
|
|
77
63
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
const { startAfter, singletonSeconds, singletonMinutes, singletonHours } = options
|
|
85
|
-
|
|
86
|
-
options.startAfter = (startAfter instanceof Date && typeof startAfter.toISOString === 'function')
|
|
87
|
-
? startAfter.toISOString()
|
|
88
|
-
: (startAfter > 0)
|
|
89
|
-
? '' + startAfter
|
|
90
|
-
: (typeof startAfter === 'string')
|
|
91
|
-
? startAfter
|
|
64
|
+
options.startAfter = (options.startAfter instanceof Date && typeof options.startAfter.toISOString === 'function')
|
|
65
|
+
? options.startAfter.toISOString()
|
|
66
|
+
: (options.startAfter > 0)
|
|
67
|
+
? '' + options.startAfter
|
|
68
|
+
: (typeof options.startAfter === 'string')
|
|
69
|
+
? options.startAfter
|
|
92
70
|
: null
|
|
93
71
|
|
|
94
|
-
options
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
: (singletonSeconds > 0)
|
|
99
|
-
? singletonSeconds
|
|
100
|
-
: null
|
|
101
|
-
|
|
102
|
-
assert(!singletonSeconds || singletonSeconds <= defaults.archiveSeconds, `throttling interval ${singletonSeconds}s cannot exceed archive interval ${defaults.archiveSeconds}s`)
|
|
103
|
-
|
|
104
|
-
if (options.onComplete) {
|
|
105
|
-
emitWarning(WARNINGS.ON_COMPLETE_REMOVED)
|
|
106
|
-
}
|
|
72
|
+
validateRetryConfig(options)
|
|
73
|
+
validateExpirationConfig(options)
|
|
74
|
+
validateRetentionConfig(options)
|
|
75
|
+
validateDeletionConfig(options)
|
|
107
76
|
|
|
108
77
|
return { name, data, options }
|
|
109
78
|
}
|
|
110
79
|
|
|
111
|
-
function checkWorkArgs (name, args
|
|
80
|
+
function checkWorkArgs (name, args) {
|
|
112
81
|
let options, callback
|
|
113
82
|
|
|
114
83
|
assert(name, 'missing job name')
|
|
@@ -126,7 +95,7 @@ function checkWorkArgs (name, args, defaults) {
|
|
|
126
95
|
|
|
127
96
|
options = { ...options }
|
|
128
97
|
|
|
129
|
-
applyPollingInterval(options
|
|
98
|
+
applyPollingInterval(options)
|
|
130
99
|
|
|
131
100
|
assert(!('batchSize' in options) || (Number.isInteger(options.batchSize) && options.batchSize >= 1), 'batchSize must be an integer > 0')
|
|
132
101
|
assert(!('includeMetadata' in options) || typeof options.includeMetadata === 'boolean', 'includeMetadata must be a boolean')
|
|
@@ -162,14 +131,8 @@ function getConfig (value) {
|
|
|
162
131
|
|
|
163
132
|
applySchemaConfig(config)
|
|
164
133
|
applyMaintenanceConfig(config)
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
applyDeleteConfig(config)
|
|
168
|
-
applyMonitoringConfig(config)
|
|
169
|
-
|
|
170
|
-
applyPollingInterval(config)
|
|
171
|
-
applyExpirationConfig(config)
|
|
172
|
-
applyRetentionConfig(config)
|
|
134
|
+
applyScheduleConfig(config)
|
|
135
|
+
validateWarningConfig(config)
|
|
173
136
|
|
|
174
137
|
return config
|
|
175
138
|
}
|
|
@@ -182,6 +145,14 @@ function applySchemaConfig (config) {
|
|
|
182
145
|
config.schema = config.schema || DEFAULT_SCHEMA
|
|
183
146
|
}
|
|
184
147
|
|
|
148
|
+
function validateWarningConfig (config) {
|
|
149
|
+
assert(!('warningQueueSize' in config) || config.warningQueueSize >= 1,
|
|
150
|
+
'configuration assert: warningQueueSize must be at least 1')
|
|
151
|
+
|
|
152
|
+
assert(!('warningSlowQuerySeconds' in config) || config.warningSlowQuerySeconds >= 1,
|
|
153
|
+
'configuration assert: warningSlowQuerySeconds must be at least 1')
|
|
154
|
+
}
|
|
155
|
+
|
|
185
156
|
function assertPostgresObjectName (name) {
|
|
186
157
|
assert(typeof name === 'string', 'Name must be a string')
|
|
187
158
|
assert(name.length <= 50, 'Name cannot exceed 50 characters')
|
|
@@ -195,207 +166,85 @@ function assertQueueName (name) {
|
|
|
195
166
|
assert(/[\w-]/.test(name), 'Name can only contain alphanumeric characters, underscores, or hyphens')
|
|
196
167
|
}
|
|
197
168
|
|
|
198
|
-
function
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
assert(
|
|
202
|
-
'configuration assert: archiveCompletedAfterSeconds must be at least every second and less than ')
|
|
203
|
-
|
|
204
|
-
config.archiveSeconds = config.archiveCompletedAfterSeconds || ARCHIVE_DEFAULT
|
|
205
|
-
config.archiveInterval = `${config.archiveSeconds} seconds`
|
|
206
|
-
|
|
207
|
-
if (config.archiveSeconds < 60) {
|
|
208
|
-
emitWarning(WARNINGS.CRON_DISABLED)
|
|
209
|
-
}
|
|
169
|
+
function assertKey (key) {
|
|
170
|
+
if (!key) return
|
|
171
|
+
assert(typeof key === 'string', 'Key must be a string')
|
|
172
|
+
assert(/[\w-]/.test(key), 'Key can only contain alphanumeric characters, underscores, or hyphens')
|
|
210
173
|
}
|
|
211
174
|
|
|
212
|
-
function
|
|
213
|
-
assert(!('archiveFailedAfterSeconds' in config) || config.archiveFailedAfterSeconds >= 1,
|
|
214
|
-
'configuration assert: archiveFailedAfterSeconds must be at least every second and less than ')
|
|
215
|
-
|
|
216
|
-
config.archiveFailedSeconds = config.archiveFailedAfterSeconds || config.archiveSeconds
|
|
217
|
-
config.archiveFailedInterval = `${config.archiveFailedSeconds} seconds`
|
|
218
|
-
|
|
219
|
-
// Do not emit warning twice
|
|
220
|
-
if (config.archiveFailedSeconds < 60 && config.archiveSeconds >= 60) {
|
|
221
|
-
emitWarning(WARNINGS.CRON_DISABLED)
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
function applyRetentionConfig (config, defaults = {}) {
|
|
175
|
+
function validateRetentionConfig (config) {
|
|
226
176
|
assert(!('retentionSeconds' in config) || config.retentionSeconds >= 1,
|
|
227
177
|
'configuration assert: retentionSeconds must be at least every second')
|
|
228
|
-
|
|
229
|
-
assert(!('retentionMinutes' in config) || config.retentionMinutes >= 1,
|
|
230
|
-
'configuration assert: retentionMinutes must be at least every minute')
|
|
231
|
-
|
|
232
|
-
assert(!('retentionHours' in config) || config.retentionHours >= 1,
|
|
233
|
-
'configuration assert: retentionHours must be at least every hour')
|
|
234
|
-
|
|
235
|
-
assert(!('retentionDays' in config) || config.retentionDays >= 1,
|
|
236
|
-
'configuration assert: retentionDays must be at least every day')
|
|
237
|
-
|
|
238
|
-
const keepUntil = ('retentionDays' in config)
|
|
239
|
-
? `${config.retentionDays} days`
|
|
240
|
-
: ('retentionHours' in config)
|
|
241
|
-
? `${config.retentionHours} hours`
|
|
242
|
-
: ('retentionMinutes' in config)
|
|
243
|
-
? `${config.retentionMinutes} minutes`
|
|
244
|
-
: ('retentionSeconds' in config)
|
|
245
|
-
? `${config.retentionSeconds} seconds`
|
|
246
|
-
: null
|
|
247
|
-
|
|
248
|
-
config.keepUntil = keepUntil
|
|
249
|
-
config.keepUntilDefault = defaults?.keepUntil
|
|
250
178
|
}
|
|
251
179
|
|
|
252
|
-
function
|
|
180
|
+
function validateExpirationConfig (config) {
|
|
253
181
|
assert(!('expireInSeconds' in config) || config.expireInSeconds >= 1,
|
|
254
182
|
'configuration assert: expireInSeconds must be at least every second')
|
|
255
183
|
|
|
256
|
-
assert(!
|
|
257
|
-
'configuration assert: expireInMinutes must be at least every minute')
|
|
258
|
-
|
|
259
|
-
assert(!('expireInHours' in config) || config.expireInHours >= 1,
|
|
260
|
-
'configuration assert: expireInHours must be at least every hour')
|
|
261
|
-
|
|
262
|
-
const expireIn = ('expireInHours' in config)
|
|
263
|
-
? config.expireInHours * 60 * 60
|
|
264
|
-
: ('expireInMinutes' in config)
|
|
265
|
-
? config.expireInMinutes * 60
|
|
266
|
-
: ('expireInSeconds' in config)
|
|
267
|
-
? config.expireInSeconds
|
|
268
|
-
: null
|
|
269
|
-
|
|
270
|
-
assert(!expireIn || expireIn / 60 / 60 < POLICY.MAX_EXPIRATION_HOURS, `configuration assert: expiration cannot exceed ${POLICY.MAX_EXPIRATION_HOURS} hours`)
|
|
271
|
-
|
|
272
|
-
config.expireIn = expireIn
|
|
273
|
-
config.expireInDefault = defaults?.expireIn
|
|
184
|
+
assert(!config.expireInSeconds || config.expireInSeconds / 60 / 60 < POLICY.MAX_EXPIRATION_HOURS, `configuration assert: expiration cannot exceed ${POLICY.MAX_EXPIRATION_HOURS} hours`)
|
|
274
185
|
}
|
|
275
186
|
|
|
276
|
-
function
|
|
187
|
+
function validateRetryConfig (config) {
|
|
277
188
|
assert(!('retryDelay' in config) || (Number.isInteger(config.retryDelay) && config.retryDelay >= 0), 'retryDelay must be an integer >= 0')
|
|
278
189
|
assert(!('retryLimit' in config) || (Number.isInteger(config.retryLimit) && config.retryLimit >= 0), 'retryLimit must be an integer >= 0')
|
|
279
190
|
assert(!('retryBackoff' in config) || (config.retryBackoff === true || config.retryBackoff === false), 'retryBackoff must be either true or false')
|
|
280
|
-
|
|
281
|
-
config.
|
|
282
|
-
config.retryLimitDefault = defaults?.retryLimit
|
|
283
|
-
config.retryBackoffDefault = defaults?.retryBackoff
|
|
191
|
+
assert(!('retryDelayMax' in config) || config.retryDelayMax === null || config.retryBackoff === true, 'retryDelayMax can only be set if retryBackoff is true')
|
|
192
|
+
assert(!('retryDelayMax' in config) || config.retryDelayMax === null || (Number.isInteger(config.retryDelayMax) && config.retryDelayMax >= 0), 'retryDelayMax must be an integer >= 0')
|
|
284
193
|
}
|
|
285
194
|
|
|
286
|
-
function applyPollingInterval (config
|
|
195
|
+
function applyPollingInterval (config) {
|
|
287
196
|
assert(!('pollingIntervalSeconds' in config) || config.pollingIntervalSeconds >= POLICY.MIN_POLLING_INTERVAL_MS / 1000,
|
|
288
197
|
`configuration assert: pollingIntervalSeconds must be at least every ${POLICY.MIN_POLLING_INTERVAL_MS}ms`)
|
|
289
198
|
|
|
290
199
|
config.pollingInterval = ('pollingIntervalSeconds' in config)
|
|
291
200
|
? config.pollingIntervalSeconds * 1000
|
|
292
|
-
:
|
|
201
|
+
: 2000
|
|
293
202
|
}
|
|
294
203
|
|
|
295
204
|
function applyMaintenanceConfig (config) {
|
|
296
205
|
assert(!('maintenanceIntervalSeconds' in config) || config.maintenanceIntervalSeconds >= 1,
|
|
297
206
|
'configuration assert: maintenanceIntervalSeconds must be at least every second')
|
|
298
207
|
|
|
299
|
-
|
|
300
|
-
'configuration assert: maintenanceIntervalMinutes must be at least every minute')
|
|
208
|
+
config.maintenanceIntervalSeconds = config.maintenanceIntervalSeconds || POLICY.MAX_EXPIRATION_HOURS * 60 * 60
|
|
301
209
|
|
|
302
|
-
config.maintenanceIntervalSeconds
|
|
303
|
-
|
|
304
|
-
: ('maintenanceIntervalSeconds' in config)
|
|
305
|
-
? config.maintenanceIntervalSeconds
|
|
306
|
-
: 120
|
|
210
|
+
assert(config.maintenanceIntervalSeconds / 60 / 60 <= POLICY.MAX_EXPIRATION_HOURS,
|
|
211
|
+
`configuration assert: maintenanceIntervalSeconds cannot exceed ${POLICY.MAX_EXPIRATION_HOURS} hours`)
|
|
307
212
|
|
|
308
|
-
assert(
|
|
309
|
-
|
|
310
|
-
}
|
|
213
|
+
assert(!('monitorIntervalSeconds' in config) || config.monitorIntervalSeconds >= 1,
|
|
214
|
+
'configuration assert: monitorIntervalSeconds must be at least every second')
|
|
311
215
|
|
|
312
|
-
|
|
313
|
-
assert(!('deleteAfterSeconds' in config) || config.deleteAfterSeconds >= 1,
|
|
314
|
-
'configuration assert: deleteAfterSeconds must be at least every second')
|
|
216
|
+
config.monitorIntervalSeconds = config.monitorIntervalSeconds || 60
|
|
315
217
|
|
|
316
|
-
assert(
|
|
317
|
-
|
|
218
|
+
assert(config.monitorIntervalSeconds / 60 / 60 <= POLICY.MAX_EXPIRATION_HOURS,
|
|
219
|
+
`configuration assert: monitorIntervalSeconds cannot exceed ${POLICY.MAX_EXPIRATION_HOURS} hours`)
|
|
318
220
|
|
|
319
|
-
assert(!('
|
|
320
|
-
'configuration assert:
|
|
221
|
+
assert(!('queueCacheIntervalSeconds' in config) || config.queueCacheIntervalSeconds >= 1,
|
|
222
|
+
'configuration assert: queueCacheIntervalSeconds must be at least every second')
|
|
321
223
|
|
|
322
|
-
|
|
323
|
-
'configuration assert: deleteAfterDays must be at least every day')
|
|
224
|
+
config.queueCacheIntervalSeconds = config.queueCacheIntervalSeconds || 60
|
|
324
225
|
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
: ('deleteAfterHours' in config)
|
|
328
|
-
? `${config.deleteAfterHours} hours`
|
|
329
|
-
: ('deleteAfterMinutes' in config)
|
|
330
|
-
? `${config.deleteAfterMinutes} minutes`
|
|
331
|
-
: ('deleteAfterSeconds' in config)
|
|
332
|
-
? `${config.deleteAfterSeconds} seconds`
|
|
333
|
-
: '7 days'
|
|
334
|
-
|
|
335
|
-
config.deleteAfter = deleteAfter
|
|
226
|
+
assert(config.queueCacheIntervalSeconds / 60 / 60 <= POLICY.MAX_EXPIRATION_HOURS,
|
|
227
|
+
`configuration assert: queueCacheIntervalSeconds cannot exceed ${POLICY.MAX_EXPIRATION_HOURS} hours`)
|
|
336
228
|
}
|
|
337
229
|
|
|
338
|
-
function
|
|
339
|
-
assert(!('
|
|
340
|
-
'configuration assert:
|
|
341
|
-
|
|
342
|
-
assert(!('monitorStateIntervalMinutes' in config) || config.monitorStateIntervalMinutes >= 1,
|
|
343
|
-
'configuration assert: monitorStateIntervalMinutes must be at least every minute')
|
|
344
|
-
|
|
345
|
-
config.monitorStateIntervalSeconds =
|
|
346
|
-
('monitorStateIntervalMinutes' in config)
|
|
347
|
-
? config.monitorStateIntervalMinutes * 60
|
|
348
|
-
: ('monitorStateIntervalSeconds' in config)
|
|
349
|
-
? config.monitorStateIntervalSeconds
|
|
350
|
-
: null
|
|
351
|
-
|
|
352
|
-
if (config.monitorStateIntervalSeconds) {
|
|
353
|
-
assert(config.monitorStateIntervalSeconds / 60 / 60 < POLICY.MAX_EXPIRATION_HOURS,
|
|
354
|
-
`configuration assert: state monitoring interval cannot exceed ${POLICY.MAX_EXPIRATION_HOURS} hours`)
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
const TEN_MINUTES_IN_SECONDS = 600
|
|
230
|
+
function validateDeletionConfig (config) {
|
|
231
|
+
assert(!('deleteAfterSeconds' in config) || config.deleteAfterSeconds >= 1,
|
|
232
|
+
'configuration assert: deleteAfterSeconds must be at least every second')
|
|
233
|
+
}
|
|
358
234
|
|
|
359
|
-
|
|
235
|
+
function applyScheduleConfig (config) {
|
|
236
|
+
assert(!('clockMonitorIntervalSeconds' in config) || (config.clockMonitorIntervalSeconds >= 1 && config.clockMonitorIntervalSeconds <= 600),
|
|
360
237
|
'configuration assert: clockMonitorIntervalSeconds must be between 1 second and 10 minutes')
|
|
361
238
|
|
|
362
|
-
|
|
363
|
-
'configuration assert: clockMonitorIntervalMinutes must be between 1 and 10')
|
|
364
|
-
|
|
365
|
-
config.clockMonitorIntervalSeconds =
|
|
366
|
-
('clockMonitorIntervalMinutes' in config)
|
|
367
|
-
? config.clockMonitorIntervalMinutes * 60
|
|
368
|
-
: ('clockMonitorIntervalSeconds' in config)
|
|
369
|
-
? config.clockMonitorIntervalSeconds
|
|
370
|
-
: TEN_MINUTES_IN_SECONDS
|
|
239
|
+
config.clockMonitorIntervalSeconds = config.clockMonitorIntervalSeconds || 600
|
|
371
240
|
|
|
372
241
|
assert(!('cronMonitorIntervalSeconds' in config) || (config.cronMonitorIntervalSeconds >= 1 && config.cronMonitorIntervalSeconds <= 45),
|
|
373
242
|
'configuration assert: cronMonitorIntervalSeconds must be between 1 and 45 seconds')
|
|
374
243
|
|
|
375
|
-
config.cronMonitorIntervalSeconds =
|
|
376
|
-
('cronMonitorIntervalSeconds' in config)
|
|
377
|
-
? config.cronMonitorIntervalSeconds
|
|
378
|
-
: 30
|
|
244
|
+
config.cronMonitorIntervalSeconds = config.cronMonitorIntervalSeconds || 30
|
|
379
245
|
|
|
380
246
|
assert(!('cronWorkerIntervalSeconds' in config) || (config.cronWorkerIntervalSeconds >= 1 && config.cronWorkerIntervalSeconds <= 45),
|
|
381
247
|
'configuration assert: cronWorkerIntervalSeconds must be between 1 and 45 seconds')
|
|
382
248
|
|
|
383
|
-
config.cronWorkerIntervalSeconds =
|
|
384
|
-
('cronWorkerIntervalSeconds' in config)
|
|
385
|
-
? config.cronWorkerIntervalSeconds
|
|
386
|
-
: 5
|
|
387
|
-
}
|
|
388
|
-
|
|
389
|
-
function warnClockSkew (message) {
|
|
390
|
-
emitWarning(WARNINGS.CLOCK_SKEW, message, { force: true })
|
|
391
|
-
}
|
|
392
|
-
|
|
393
|
-
function emitWarning (warning, message, options = {}) {
|
|
394
|
-
const { force } = options
|
|
395
|
-
|
|
396
|
-
if (force || !warning.warned) {
|
|
397
|
-
warning.warned = true
|
|
398
|
-
message = `${warning.message} ${message || ''}`
|
|
399
|
-
process.emitWarning(message, warning.type, warning.code)
|
|
400
|
-
}
|
|
249
|
+
config.cronWorkerIntervalSeconds = config.cronWorkerIntervalSeconds || 5
|
|
401
250
|
}
|