pg-boss 9.0.3 → 10.0.0-beta10
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 +19 -40
- package/package.json +7 -11
- package/src/attorney.js +81 -105
- package/src/boss.js +88 -139
- package/src/contractor.js +25 -4
- package/src/db.js +14 -8
- package/src/index.js +128 -93
- package/src/manager.js +222 -142
- package/src/migrationStore.js +0 -105
- package/src/plans.js +437 -361
- package/src/timekeeper.js +45 -82
- package/src/tools.js +28 -0
- package/src/worker.js +4 -4
- package/types.d.ts +76 -70
- package/version.json +1 -1
package/src/index.js
CHANGED
|
@@ -6,13 +6,24 @@ const Manager = require('./manager')
|
|
|
6
6
|
const Timekeeper = require('./timekeeper')
|
|
7
7
|
const Boss = require('./boss')
|
|
8
8
|
const Db = require('./db')
|
|
9
|
-
const delay = require('
|
|
9
|
+
const { delay } = require('./tools')
|
|
10
10
|
|
|
11
11
|
const events = {
|
|
12
12
|
error: 'error',
|
|
13
13
|
stopped: 'stopped'
|
|
14
14
|
}
|
|
15
15
|
class PgBoss extends EventEmitter {
|
|
16
|
+
#stoppingOn
|
|
17
|
+
#stopped
|
|
18
|
+
#starting
|
|
19
|
+
#started
|
|
20
|
+
#config
|
|
21
|
+
#db
|
|
22
|
+
#boss
|
|
23
|
+
#contractor
|
|
24
|
+
#manager
|
|
25
|
+
#timekeeper
|
|
26
|
+
|
|
16
27
|
static getConstructionPlans (schema) {
|
|
17
28
|
return Contractor.constructionPlans(schema)
|
|
18
29
|
}
|
|
@@ -25,158 +36,182 @@ class PgBoss extends EventEmitter {
|
|
|
25
36
|
return Contractor.rollbackPlans(schema, version)
|
|
26
37
|
}
|
|
27
38
|
|
|
28
|
-
|
|
29
|
-
|
|
39
|
+
static states = plans.JOB_STATES
|
|
40
|
+
static policies = plans.QUEUE_POLICIES
|
|
30
41
|
|
|
42
|
+
constructor (value) {
|
|
31
43
|
super()
|
|
32
44
|
|
|
33
|
-
|
|
45
|
+
this.#stoppingOn = null
|
|
46
|
+
this.#stopped = true
|
|
47
|
+
|
|
48
|
+
const config = Attorney.getConfig(value)
|
|
49
|
+
this.#config = config
|
|
50
|
+
|
|
51
|
+
const db = this.getDb()
|
|
52
|
+
this.#db = db
|
|
34
53
|
|
|
35
54
|
if (db.isOurs) {
|
|
36
|
-
|
|
55
|
+
this.#promoteEvents(db)
|
|
37
56
|
}
|
|
38
57
|
|
|
39
|
-
const
|
|
40
|
-
Object.keys(manager.events).forEach(event => promoteEvent.call(this, manager, manager.events[event]))
|
|
41
|
-
manager.functions.forEach(func => promoteFunction.call(this, manager, func))
|
|
58
|
+
const contractor = new Contractor(db, config)
|
|
42
59
|
|
|
60
|
+
const manager = new Manager(db, config)
|
|
43
61
|
const bossConfig = { ...config, manager }
|
|
44
62
|
|
|
45
63
|
const boss = new Boss(db, bossConfig)
|
|
46
|
-
Object.keys(boss.events).forEach(event => promoteEvent.call(this, boss, boss.events[event]))
|
|
47
|
-
boss.functions.forEach(func => promoteFunction.call(this, boss, func))
|
|
48
64
|
|
|
49
65
|
const timekeeper = new Timekeeper(db, bossConfig)
|
|
50
|
-
Object.keys(timekeeper.events).forEach(event => promoteEvent.call(this, timekeeper, timekeeper.events[event]))
|
|
51
|
-
timekeeper.functions.forEach(func => promoteFunction.call(this, timekeeper, func))
|
|
52
|
-
|
|
53
66
|
manager.timekeeper = timekeeper
|
|
54
67
|
|
|
55
|
-
this
|
|
56
|
-
this
|
|
57
|
-
this
|
|
58
|
-
this.db = db
|
|
59
|
-
this.boss = boss
|
|
60
|
-
this.contractor = new Contractor(db, config)
|
|
61
|
-
this.manager = manager
|
|
62
|
-
this.timekeeper = timekeeper
|
|
63
|
-
|
|
64
|
-
function getDb (config) {
|
|
65
|
-
if (config.db) {
|
|
66
|
-
return config.db
|
|
67
|
-
}
|
|
68
|
+
this.#promoteEvents(manager)
|
|
69
|
+
this.#promoteEvents(boss)
|
|
70
|
+
this.#promoteEvents(timekeeper)
|
|
68
71
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
72
|
+
this.#promoteFunctions(boss)
|
|
73
|
+
this.#promoteFunctions(contractor)
|
|
74
|
+
this.#promoteFunctions(manager)
|
|
75
|
+
this.#promoteFunctions(timekeeper)
|
|
73
76
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
+
this.#boss = boss
|
|
78
|
+
this.#contractor = contractor
|
|
79
|
+
this.#manager = manager
|
|
80
|
+
this.#timekeeper = timekeeper
|
|
81
|
+
}
|
|
77
82
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
83
|
+
getDb () {
|
|
84
|
+
if (this.#db) {
|
|
85
|
+
return this.#db
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
if (this.#config.db) {
|
|
89
|
+
return this.#config.db
|
|
85
90
|
}
|
|
86
91
|
|
|
87
|
-
|
|
92
|
+
const db = new Db(this.#config)
|
|
93
|
+
db.isOurs = true
|
|
94
|
+
return db
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
#promoteEvents (emitter) {
|
|
98
|
+
for (const event of Object.values(emitter?.events)) {
|
|
88
99
|
emitter.on(event, arg => this.emit(event, arg))
|
|
89
100
|
}
|
|
90
101
|
}
|
|
91
102
|
|
|
103
|
+
#promoteFunctions (obj) {
|
|
104
|
+
for (const func of obj?.functions) {
|
|
105
|
+
this[func.name] = (...args) => func.apply(obj, args)
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
92
109
|
async start () {
|
|
93
|
-
if (
|
|
94
|
-
return
|
|
110
|
+
if (this.#starting || this.#started) {
|
|
111
|
+
return
|
|
95
112
|
}
|
|
96
113
|
|
|
97
|
-
|
|
98
|
-
|
|
114
|
+
this.#starting = true
|
|
115
|
+
|
|
116
|
+
if (this.#db.isOurs && !this.#db.opened) {
|
|
117
|
+
await this.#db.open()
|
|
99
118
|
}
|
|
100
119
|
|
|
101
|
-
|
|
120
|
+
if (this.#config.migrate) {
|
|
121
|
+
await this.#contractor.start()
|
|
122
|
+
} else {
|
|
123
|
+
await this.#contractor.check()
|
|
124
|
+
}
|
|
102
125
|
|
|
103
|
-
this.
|
|
104
|
-
this.started = true
|
|
126
|
+
this.#manager.start()
|
|
105
127
|
|
|
106
|
-
this.
|
|
128
|
+
if (this.#config.supervise) {
|
|
129
|
+
await this.#boss.supervise()
|
|
130
|
+
}
|
|
107
131
|
|
|
108
|
-
if (
|
|
109
|
-
await this
|
|
132
|
+
if (this.#config.monitorStateIntervalSeconds) {
|
|
133
|
+
await this.#boss.monitor()
|
|
110
134
|
}
|
|
111
135
|
|
|
112
|
-
if (
|
|
113
|
-
await this
|
|
136
|
+
if (this.#config.schedule) {
|
|
137
|
+
await this.#timekeeper.start()
|
|
114
138
|
}
|
|
115
139
|
|
|
140
|
+
this.#starting = false
|
|
141
|
+
this.#started = true
|
|
142
|
+
this.#stopped = false
|
|
143
|
+
|
|
116
144
|
return this
|
|
117
145
|
}
|
|
118
146
|
|
|
119
147
|
async stop (options = {}) {
|
|
120
|
-
if (this
|
|
148
|
+
if (this.#stoppingOn || this.#stopped) {
|
|
121
149
|
return
|
|
122
150
|
}
|
|
123
151
|
|
|
124
|
-
|
|
125
|
-
this.emit(events.stopped)
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
let { destroy = false, graceful = true, timeout = 30000 } = options
|
|
152
|
+
let { destroy = false, graceful = true, timeout = 30000, wait = true } = options
|
|
129
153
|
|
|
130
154
|
timeout = Math.max(timeout, 1000)
|
|
131
155
|
|
|
132
|
-
this
|
|
156
|
+
this.#stoppingOn = Date.now()
|
|
133
157
|
|
|
134
|
-
await this
|
|
135
|
-
await this
|
|
158
|
+
await this.#manager.stop()
|
|
159
|
+
await this.#timekeeper.stop()
|
|
160
|
+
await this.#boss.stop()
|
|
136
161
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
162
|
+
await new Promise((resolve, reject) => {
|
|
163
|
+
const shutdown = async () => {
|
|
164
|
+
try {
|
|
165
|
+
if (this.#config.__test__throw_shutdown) {
|
|
166
|
+
throw new Error(this.#config.__test__throw_shutdown)
|
|
167
|
+
}
|
|
140
168
|
|
|
141
|
-
|
|
142
|
-
await this.db.close()
|
|
143
|
-
}
|
|
169
|
+
await this.#manager.failWip()
|
|
144
170
|
|
|
145
|
-
|
|
146
|
-
|
|
171
|
+
if (this.#db.isOurs && this.#db.opened && destroy) {
|
|
172
|
+
await this.#db.close()
|
|
173
|
+
}
|
|
147
174
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
return
|
|
152
|
-
}
|
|
175
|
+
this.#stopped = true
|
|
176
|
+
this.#stoppingOn = null
|
|
177
|
+
this.#started = false
|
|
153
178
|
|
|
154
|
-
|
|
155
|
-
|
|
179
|
+
this.emit(events.stopped)
|
|
180
|
+
resolve()
|
|
181
|
+
} catch (err) {
|
|
182
|
+
this.emit(events.error, err)
|
|
183
|
+
reject(err)
|
|
184
|
+
}
|
|
185
|
+
}
|
|
156
186
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
if (closing) {
|
|
161
|
-
break
|
|
162
|
-
}
|
|
187
|
+
if (!graceful) {
|
|
188
|
+
return shutdown()
|
|
189
|
+
}
|
|
163
190
|
|
|
164
|
-
|
|
191
|
+
if (!wait) {
|
|
192
|
+
resolve()
|
|
193
|
+
}
|
|
165
194
|
|
|
166
|
-
|
|
195
|
+
setImmediate(async () => {
|
|
196
|
+
try {
|
|
197
|
+
if (this.#config.__test__throw_stop_monitor) {
|
|
198
|
+
throw new Error(this.#config.__test__throw_stop_monitor)
|
|
167
199
|
}
|
|
168
200
|
|
|
169
|
-
|
|
170
|
-
}
|
|
201
|
+
const isWip = () => this.#manager.getWipData({ includeInternal: false }).length > 0
|
|
171
202
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
203
|
+
while ((Date.now() - this.#stoppingOn) < timeout && isWip()) {
|
|
204
|
+
await delay(500)
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
await shutdown()
|
|
208
|
+
} catch (err) {
|
|
209
|
+
reject(err)
|
|
210
|
+
this.emit(events.error, err)
|
|
211
|
+
}
|
|
212
|
+
})
|
|
177
213
|
})
|
|
178
214
|
}
|
|
179
215
|
}
|
|
180
216
|
|
|
181
217
|
module.exports = PgBoss
|
|
182
|
-
module.exports.states = plans.states
|