pg-boss 10.0.0-beta19 → 10.0.0-beta20
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 +2 -1
- package/package.json +1 -1
- package/src/boss.js +0 -28
- package/src/contractor.js +9 -9
- package/src/db.js +9 -9
- package/src/plans.js +4 -1
- package/src/timekeeper.js +9 -9
- package/types.d.ts +2 -2
package/README.md
CHANGED
|
@@ -27,10 +27,11 @@ async function readme() {
|
|
|
27
27
|
|
|
28
28
|
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.
|
|
29
29
|
|
|
30
|
-
pg-boss relies on [SKIP LOCKED](https://www.2ndquadrant.com/en/blog/what-is-select-skip-locked-for-in-postgresql-9-5/), a feature added to postgres specifically for message queues
|
|
30
|
+
pg-boss relies on [SKIP LOCKED](https://www.2ndquadrant.com/en/blog/what-is-select-skip-locked-for-in-postgresql-9-5/), a feature added to postgres 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 of a relational database to asynchronous job processing.
|
|
31
31
|
|
|
32
32
|
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.
|
|
33
33
|
|
|
34
|
+
|
|
34
35
|
## Features
|
|
35
36
|
* Exactly-once job delivery
|
|
36
37
|
* Backpressure-compatible polling workers
|
package/package.json
CHANGED
package/src/boss.js
CHANGED
|
@@ -171,34 +171,6 @@ class Boss extends EventEmitter {
|
|
|
171
171
|
async drop () {
|
|
172
172
|
await this.db.executeSql(this.dropCommand)
|
|
173
173
|
}
|
|
174
|
-
|
|
175
|
-
async setMaintenanceTime () {
|
|
176
|
-
await this.db.executeSql(this.setMaintenanceTimeCommand)
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
async getMaintenanceTime () {
|
|
180
|
-
const { rows } = await this.db.executeSql(this.getMaintenanceTimeCommand)
|
|
181
|
-
|
|
182
|
-
let { maintained_on: maintainedOn, seconds_ago: secondsAgo } = rows[0]
|
|
183
|
-
|
|
184
|
-
secondsAgo = secondsAgo !== null ? parseFloat(secondsAgo) : 999_999_999
|
|
185
|
-
|
|
186
|
-
return { maintainedOn, secondsAgo }
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
async setMonitorTime () {
|
|
190
|
-
await this.db.executeSql(this.setMonitorTimeCommand)
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
async getMonitorTime () {
|
|
194
|
-
const { rows } = await this.db.executeSql(this.getMonitorTimeCommand)
|
|
195
|
-
|
|
196
|
-
let { monitored_on: monitoredOn, seconds_ago: secondsAgo } = rows[0]
|
|
197
|
-
|
|
198
|
-
secondsAgo = secondsAgo !== null ? parseFloat(secondsAgo) : 999_999_999
|
|
199
|
-
|
|
200
|
-
return { monitoredOn, secondsAgo }
|
|
201
|
-
}
|
|
202
174
|
}
|
|
203
175
|
|
|
204
176
|
module.exports = Boss
|
package/src/contractor.js
CHANGED
|
@@ -86,15 +86,15 @@ class Contractor {
|
|
|
86
86
|
}
|
|
87
87
|
}
|
|
88
88
|
|
|
89
|
-
async next (version) {
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
async rollback (version) {
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
}
|
|
89
|
+
// async next (version) {
|
|
90
|
+
// const commands = migrationStore.next(this.config.schema, version, this.migrations)
|
|
91
|
+
// await this.db.executeSql(commands)
|
|
92
|
+
// }
|
|
93
|
+
|
|
94
|
+
// async rollback (version) {
|
|
95
|
+
// const commands = migrationStore.rollback(this.config.schema, version, this.migrations)
|
|
96
|
+
// await this.db.executeSql(commands)
|
|
97
|
+
// }
|
|
98
98
|
}
|
|
99
99
|
|
|
100
100
|
module.exports = Contractor
|
package/src/db.js
CHANGED
|
@@ -29,15 +29,15 @@ class Db extends EventEmitter {
|
|
|
29
29
|
|
|
30
30
|
async executeSql (text, values) {
|
|
31
31
|
if (this.opened) {
|
|
32
|
-
if (this.config.debug === true) {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
}
|
|
32
|
+
// if (this.config.debug === true) {
|
|
33
|
+
// console.log(`${new Date().toISOString()}: DEBUG SQL`)
|
|
34
|
+
// console.log(text)
|
|
35
|
+
|
|
36
|
+
// if (values) {
|
|
37
|
+
// console.log(`${new Date().toISOString()}: DEBUG VALUES`)
|
|
38
|
+
// console.log(values)
|
|
39
|
+
// }
|
|
40
|
+
// }
|
|
41
41
|
|
|
42
42
|
return await this.pool.query(text, values)
|
|
43
43
|
}
|
package/src/plans.js
CHANGED
|
@@ -390,13 +390,16 @@ function updateQueue (schema) {
|
|
|
390
390
|
function getQueues (schema) {
|
|
391
391
|
return `
|
|
392
392
|
SELECT
|
|
393
|
+
name,
|
|
393
394
|
policy,
|
|
394
395
|
retry_limit as "retryLimit",
|
|
395
396
|
retry_delay as "retryDelay",
|
|
396
397
|
retry_backoff as "retryBackoff",
|
|
397
398
|
expire_seconds as "expireInSeconds",
|
|
398
399
|
retention_minutes as "retentionMinutes",
|
|
399
|
-
dead_letter as "deadLetter"
|
|
400
|
+
dead_letter as "deadLetter",
|
|
401
|
+
created_on as "createdOn",
|
|
402
|
+
updated_on as "updatedOn"
|
|
400
403
|
FROM ${schema}.queue
|
|
401
404
|
`
|
|
402
405
|
}
|
package/src/timekeeper.js
CHANGED
|
@@ -173,19 +173,19 @@ class Timekeeper extends EventEmitter {
|
|
|
173
173
|
|
|
174
174
|
cronParser.parseExpression(cron, { tz })
|
|
175
175
|
|
|
176
|
-
// validation pre-check
|
|
177
176
|
Attorney.checkSendArgs([name, data, options], this.config)
|
|
178
177
|
|
|
179
|
-
// make sure queue exists before scheduling
|
|
180
|
-
const queue = await this.db.executeSql(this.getQueueCommand, [name])
|
|
181
|
-
|
|
182
|
-
if (!queue.rows.length === 0) {
|
|
183
|
-
throw new Error(`Queue '${name}' not found`)
|
|
184
|
-
}
|
|
185
|
-
|
|
186
178
|
const values = [name, cron, tz, data, options]
|
|
187
179
|
|
|
188
|
-
|
|
180
|
+
try {
|
|
181
|
+
await this.db.executeSql(this.scheduleCommand, values)
|
|
182
|
+
} catch (err) {
|
|
183
|
+
if (err.message.includes('foreign key')) {
|
|
184
|
+
err.message = `Queue ${name} not found`
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
throw err
|
|
188
|
+
}
|
|
189
189
|
}
|
|
190
190
|
|
|
191
191
|
async unschedule (name) {
|
package/types.d.ts
CHANGED
|
@@ -115,7 +115,7 @@ declare namespace PgBoss {
|
|
|
115
115
|
type QueuePolicy = 'standard' | 'short' | 'singleton' | 'stately'
|
|
116
116
|
|
|
117
117
|
type Queue = RetryOptions & ExpirationOptions & RetentionOptions & { name: string, policy?: QueuePolicy, deadLetter?: string }
|
|
118
|
-
|
|
118
|
+
type QueueResult = Queue & { createdOn: Date, updatedOn: Date }
|
|
119
119
|
type ScheduleOptions = SendOptions & { tz?: string }
|
|
120
120
|
|
|
121
121
|
interface JobPollingOptions {
|
|
@@ -348,7 +348,7 @@ declare class PgBoss extends EventEmitter {
|
|
|
348
348
|
|
|
349
349
|
createQueue(name: string, options?: PgBoss.Queue): Promise<void>;
|
|
350
350
|
getQueue(name: string): Promise<PgBoss.Queue | null>;
|
|
351
|
-
getQueues(): Promise<PgBoss.
|
|
351
|
+
getQueues(): Promise<PgBoss.QueueResult[]>;
|
|
352
352
|
updateQueue(name: string, options?: PgBoss.Queue): Promise<void>;
|
|
353
353
|
deleteQueue(name: string): Promise<void>;
|
|
354
354
|
purgeQueue(name: string): Promise<void>;
|