velocious 1.0.627 → 1.0.628
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/build/background-jobs/job-runner.js +9 -1
- package/build/background-jobs/local-dispatcher.js +23 -1
- package/build/background-jobs/main.js +6 -4
- package/build/background-jobs/perform-job.js +10 -1
- package/build/background-jobs/platform-job.js +62 -0
- package/build/background-jobs/runtime.js +6 -3
- package/build/background-jobs/types.js +8 -0
- package/build/background-jobs/worker.js +3 -1
- package/build/src/background-jobs/job-runner.d.ts.map +1 -1
- package/build/src/background-jobs/job-runner.js +10 -2
- package/build/src/background-jobs/local-dispatcher.d.ts.map +1 -1
- package/build/src/background-jobs/local-dispatcher.js +24 -2
- package/build/src/background-jobs/main.d.ts.map +1 -1
- package/build/src/background-jobs/main.js +7 -5
- package/build/src/background-jobs/perform-job.d.ts +5 -1
- package/build/src/background-jobs/perform-job.d.ts.map +1 -1
- package/build/src/background-jobs/perform-job.js +11 -2
- package/build/src/background-jobs/platform-job.d.ts +34 -0
- package/build/src/background-jobs/platform-job.d.ts.map +1 -1
- package/build/src/background-jobs/platform-job.js +56 -1
- package/build/src/background-jobs/runtime.d.ts.map +1 -1
- package/build/src/background-jobs/runtime.js +7 -4
- package/build/src/background-jobs/types.d.ts +30 -0
- package/build/src/background-jobs/types.d.ts.map +1 -1
- package/build/src/background-jobs/types.js +9 -1
- package/build/src/background-jobs/worker.d.ts.map +1 -1
- package/build/src/background-jobs/worker.js +4 -2
- package/package.json +1 -1
- package/src/background-jobs/job-runner.js +9 -1
- package/src/background-jobs/local-dispatcher.js +23 -1
- package/src/background-jobs/main.js +6 -4
- package/src/background-jobs/perform-job.js +10 -1
- package/src/background-jobs/platform-job.js +62 -0
- package/src/background-jobs/runtime.js +6 -3
- package/src/background-jobs/types.js +8 -0
- package/src/background-jobs/worker.js +3 -1
|
@@ -93,6 +93,14 @@ export default async function runJobPayload(payload, {closeConnections = true, m
|
|
|
93
93
|
await registry.load()
|
|
94
94
|
const JobClass = registry.getJobByName(payload.jobName)
|
|
95
95
|
const jobInstance = new JobClass()
|
|
96
|
+
const jobArgs = payload.args || []
|
|
97
|
+
jobInstance._setBackgroundJobContext({
|
|
98
|
+
args: jobArgs,
|
|
99
|
+
jobClass: JobClass,
|
|
100
|
+
jobName: payload.jobName,
|
|
101
|
+
options: payload.options || {},
|
|
102
|
+
payload
|
|
103
|
+
})
|
|
96
104
|
/**
|
|
97
105
|
* Perform.
|
|
98
106
|
* @type {(...args: Array<ReturnType<typeof JSON.parse>>) => Promise<void>} */
|
|
@@ -107,7 +115,7 @@ export default async function runJobPayload(payload, {closeConnections = true, m
|
|
|
107
115
|
try {
|
|
108
116
|
try {
|
|
109
117
|
await configuration.withConnections({databaseIdentifiers: JobClass.databaseIdentifiers, name: `Background job runner: ${payload.jobName}`}, async () => {
|
|
110
|
-
await perform.apply(jobInstance,
|
|
118
|
+
await perform.apply(jobInstance, jobArgs)
|
|
111
119
|
})
|
|
112
120
|
} catch (error) {
|
|
113
121
|
if (error instanceof BackgroundJobRescheduleSignal) {
|
|
@@ -184,7 +184,29 @@ export default class LocalBackgroundJobsDispatcher {
|
|
|
184
184
|
configuration: this.configuration,
|
|
185
185
|
JobClass,
|
|
186
186
|
jobArgs: job.args,
|
|
187
|
-
|
|
187
|
+
jobOptions: {
|
|
188
|
+
concurrencyKey: job.concurrencyKey || undefined,
|
|
189
|
+
executionMode: job.executionMode,
|
|
190
|
+
maxConcurrency: job.maxConcurrency ?? undefined,
|
|
191
|
+
maxRetries: job.maxRetries ?? undefined,
|
|
192
|
+
queue: job.queue,
|
|
193
|
+
scheduledAtMs: job.scheduledAtMs ?? undefined,
|
|
194
|
+
timeoutMs: job.timeoutMs ?? undefined
|
|
195
|
+
},
|
|
196
|
+
name: `Local background job: ${job.jobName}`,
|
|
197
|
+
payload: {
|
|
198
|
+
args: job.args,
|
|
199
|
+
handedOffAtMs: handoff.handedOffAtMs,
|
|
200
|
+
handoffId: handoff.handoffId,
|
|
201
|
+
id: job.id,
|
|
202
|
+
jobName: job.jobName,
|
|
203
|
+
options: {
|
|
204
|
+
concurrencyKey: job.concurrencyKey || undefined,
|
|
205
|
+
executionMode: job.executionMode,
|
|
206
|
+
maxConcurrency: job.maxConcurrency ?? undefined,
|
|
207
|
+
queue: job.queue
|
|
208
|
+
}
|
|
209
|
+
}
|
|
188
210
|
})
|
|
189
211
|
} catch (error) {
|
|
190
212
|
if (error instanceof BackgroundJobRescheduleSignal) {
|
|
@@ -223,10 +223,7 @@ export default class BackgroundJobsMain {
|
|
|
223
223
|
await this.store.enqueue({
|
|
224
224
|
jobName: jobClass.jobName(),
|
|
225
225
|
args,
|
|
226
|
-
|
|
227
|
-
// scheduled job with `static queue = "..."` lands on its queue and
|
|
228
|
-
// honors the configured cap without every schedule repeating it.
|
|
229
|
-
options: jobClass._withQueue(options)
|
|
226
|
+
options: jobClass._withJobContext({jobArgs: args, jobOptions: options})
|
|
230
227
|
})
|
|
231
228
|
this._notifyEnqueued()
|
|
232
229
|
// Persistence is the scheduler enqueue boundary. Dispatch remains
|
|
@@ -1400,7 +1397,12 @@ export default class BackgroundJobsMain {
|
|
|
1400
1397
|
workerId: worker.workerId,
|
|
1401
1398
|
handedOffAtMs: handoff.handedOffAtMs,
|
|
1402
1399
|
options: {
|
|
1400
|
+
concurrencyKey: job.concurrencyKey || undefined,
|
|
1403
1401
|
executionMode: job.executionMode,
|
|
1402
|
+
maxConcurrency: job.maxConcurrency ?? undefined,
|
|
1403
|
+
maxRetries: job.maxRetries ?? undefined,
|
|
1404
|
+
queue: job.queue,
|
|
1405
|
+
scheduledAtMs: job.scheduledAtMs ?? undefined,
|
|
1404
1406
|
...(job.timeoutMs === null ? {} : {timeoutMs: job.timeoutMs})
|
|
1405
1407
|
}
|
|
1406
1408
|
}
|
|
@@ -6,11 +6,20 @@
|
|
|
6
6
|
* @param {import("../configuration.js").default} args.configuration - Active configuration.
|
|
7
7
|
* @param {typeof import("./platform-job.js").default} args.JobClass - Job class.
|
|
8
8
|
* @param {Array<ReturnType<typeof JSON.parse>>} args.jobArgs - Job arguments.
|
|
9
|
+
* @param {import("./types.js").BackgroundJobOptions} [args.jobOptions] - Resolved runtime options.
|
|
9
10
|
* @param {string} args.name - Connection-scope label.
|
|
11
|
+
* @param {import("./types.js").BackgroundJobPayload} [args.payload] - Persisted runner payload.
|
|
10
12
|
* @returns {Promise<void>} - Resolves after performance.
|
|
11
13
|
*/
|
|
12
|
-
export default async function performBackgroundJob({configuration, JobClass, jobArgs, name}) {
|
|
14
|
+
export default async function performBackgroundJob({configuration, JobClass, jobArgs, jobOptions = {}, name, payload}) {
|
|
13
15
|
const jobInstance = new JobClass()
|
|
16
|
+
jobInstance._setBackgroundJobContext({
|
|
17
|
+
args: jobArgs,
|
|
18
|
+
jobClass: JobClass,
|
|
19
|
+
jobName: JobClass.jobName(),
|
|
20
|
+
options: jobOptions,
|
|
21
|
+
...(payload ? {payload} : {})
|
|
22
|
+
})
|
|
14
23
|
/**
|
|
15
24
|
* Narrows the generic subclass's runtime method to serialized job arguments.
|
|
16
25
|
* @type {(...args: Array<ReturnType<typeof JSON.parse>>) => Promise<void>}
|
|
@@ -14,6 +14,11 @@ import {cancelScheduledBackgroundJob, enqueueBackgroundJob, replaceScheduledBack
|
|
|
14
14
|
* @template {Array<ReturnType<typeof JSON.parse>>} [TArgs=[]]
|
|
15
15
|
*/
|
|
16
16
|
export default class VelociousJob {
|
|
17
|
+
constructor() {
|
|
18
|
+
/** @type {import("./types.js").BackgroundJobContext | undefined} */
|
|
19
|
+
this._backgroundJobContext = undefined
|
|
20
|
+
}
|
|
21
|
+
|
|
17
22
|
/**
|
|
18
23
|
* Database identifiers checked out while this job performs. Set an explicit
|
|
19
24
|
* list to avoid holding unrelated configured database connections, or `[]`
|
|
@@ -82,6 +87,63 @@ export default class VelociousJob {
|
|
|
82
87
|
return merged
|
|
83
88
|
}
|
|
84
89
|
|
|
90
|
+
/**
|
|
91
|
+
* Resolves class-derived enqueue options on a hydrated job instance. Explicit
|
|
92
|
+
* per-enqueue options take precedence over the instance concurrency key.
|
|
93
|
+
* @param {object} args - Job context.
|
|
94
|
+
* @param {Array<ReturnType<typeof JSON.parse>>} args.jobArgs - Job arguments.
|
|
95
|
+
* @param {import("./types.js").BackgroundJobOptions | undefined} args.jobOptions - Job options.
|
|
96
|
+
* @returns {import("./types.js").BackgroundJobOptions} - Resolved job options.
|
|
97
|
+
*/
|
|
98
|
+
static _withJobContext({jobArgs, jobOptions}) {
|
|
99
|
+
const options = this._withQueue(jobOptions)
|
|
100
|
+
|
|
101
|
+
if (options.concurrencyKey !== undefined) return options
|
|
102
|
+
|
|
103
|
+
const jobInstance = new this()
|
|
104
|
+
jobInstance._setBackgroundJobContext({
|
|
105
|
+
args: jobArgs,
|
|
106
|
+
jobClass: this,
|
|
107
|
+
jobName: this.jobName(),
|
|
108
|
+
options
|
|
109
|
+
})
|
|
110
|
+
const concurrencyKey = jobInstance.concurrencyKey()
|
|
111
|
+
|
|
112
|
+
if (concurrencyKey !== undefined) options.concurrencyKey = concurrencyKey
|
|
113
|
+
|
|
114
|
+
return options
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Sets the complete context available to this hydrated job instance.
|
|
119
|
+
* Framework enqueue/runner boundaries own this method.
|
|
120
|
+
* @param {import("./types.js").BackgroundJobContext} context - Job context.
|
|
121
|
+
* @returns {void}
|
|
122
|
+
*/
|
|
123
|
+
_setBackgroundJobContext(context) {
|
|
124
|
+
this._backgroundJobContext = context
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Returns this hydrated job's complete enqueue or runner context.
|
|
129
|
+
* @returns {import("./types.js").BackgroundJobContext} - Job context.
|
|
130
|
+
*/
|
|
131
|
+
backgroundJobContext() {
|
|
132
|
+
if (!this._backgroundJobContext) throw new Error("Background job context is not hydrated")
|
|
133
|
+
|
|
134
|
+
return this._backgroundJobContext
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Override to derive a durable concurrency key from `backgroundJobContext()`.
|
|
139
|
+
* Pair the derived key with `maxConcurrency` in enqueue options. An explicit
|
|
140
|
+
* per-enqueue `concurrencyKey` takes precedence and skips this method.
|
|
141
|
+
* @returns {string | undefined} - Derived concurrency key, or undefined for none.
|
|
142
|
+
*/
|
|
143
|
+
concurrencyKey() {
|
|
144
|
+
return undefined
|
|
145
|
+
}
|
|
146
|
+
|
|
85
147
|
/**
|
|
86
148
|
* Runs perform later.
|
|
87
149
|
* @param {...ReturnType<typeof JSON.parse>} args - Job args.
|
|
@@ -52,9 +52,10 @@ export async function enqueueBackgroundJob({JobClass, jobArgs, jobOptions}) {
|
|
|
52
52
|
* @returns {Promise<string>} - Durable job id or ephemeral inline performance id.
|
|
53
53
|
*/
|
|
54
54
|
export async function enqueueBackgroundJobForConfiguration({configuration, JobClass, jobArgs, jobOptions}) {
|
|
55
|
+
const resolvedJobOptions = JobClass._withJobContext({jobArgs, jobOptions})
|
|
55
56
|
|
|
56
57
|
if (configuration.getBackgroundJobsConfig().mode === "inline") {
|
|
57
|
-
validateInlineOptions(
|
|
58
|
+
validateInlineOptions(resolvedJobOptions)
|
|
58
59
|
configuration.setCurrent()
|
|
59
60
|
await configuration.initialize({type: "background-jobs-inline"})
|
|
60
61
|
|
|
@@ -63,6 +64,7 @@ export async function enqueueBackgroundJobForConfiguration({configuration, JobCl
|
|
|
63
64
|
configuration,
|
|
64
65
|
JobClass,
|
|
65
66
|
jobArgs,
|
|
67
|
+
jobOptions: resolvedJobOptions,
|
|
66
68
|
name: `Background job inline mode: ${JobClass.jobName()}`
|
|
67
69
|
})
|
|
68
70
|
} catch (error) {
|
|
@@ -81,7 +83,7 @@ export async function enqueueBackgroundJobForConfiguration({configuration, JobCl
|
|
|
81
83
|
return await client.enqueue({
|
|
82
84
|
jobName: JobClass.jobName(),
|
|
83
85
|
args: jobArgs,
|
|
84
|
-
options:
|
|
86
|
+
options: resolvedJobOptions
|
|
85
87
|
})
|
|
86
88
|
}
|
|
87
89
|
|
|
@@ -117,12 +119,13 @@ export async function replaceScheduledBackgroundJobForConfiguration({configurati
|
|
|
117
119
|
}
|
|
118
120
|
|
|
119
121
|
const client = configuration.getEnvironmentHandler().backgroundJobsClient({configuration})
|
|
122
|
+
const resolvedJobOptions = JobClass._withJobContext({jobArgs, jobOptions})
|
|
120
123
|
|
|
121
124
|
return await client.replaceScheduled({
|
|
122
125
|
scheduleKey,
|
|
123
126
|
jobName: JobClass.jobName(),
|
|
124
127
|
args: jobArgs,
|
|
125
|
-
options:
|
|
128
|
+
options: resolvedJobOptions
|
|
126
129
|
})
|
|
127
130
|
}
|
|
128
131
|
|
|
@@ -71,6 +71,14 @@
|
|
|
71
71
|
* @property {number} [handedOffAtMs] - Time handed to a worker in ms.
|
|
72
72
|
* @property {BackgroundJobOptions} [options] - Runtime options.
|
|
73
73
|
*/
|
|
74
|
+
/**
|
|
75
|
+
* @typedef {object} BackgroundJobContext
|
|
76
|
+
* @property {typeof import("./platform-job.js").default} jobClass - Concrete job class.
|
|
77
|
+
* @property {string} jobName - Registered job name.
|
|
78
|
+
* @property {Array<ReturnType<typeof JSON.parse>>} args - Serialized job arguments.
|
|
79
|
+
* @property {BackgroundJobOptions} options - Resolved enqueue/runtime options.
|
|
80
|
+
* @property {BackgroundJobPayload} [payload] - Complete persisted runner payload when the job is performing.
|
|
81
|
+
*/
|
|
74
82
|
/**
|
|
75
83
|
* @typedef {object} BackgroundJobRow
|
|
76
84
|
* @property {string} id - Job id.
|
|
@@ -1054,7 +1054,9 @@ export default class BackgroundJobsWorker {
|
|
|
1054
1054
|
configuration,
|
|
1055
1055
|
JobClass,
|
|
1056
1056
|
jobArgs: payload.args || [],
|
|
1057
|
-
|
|
1057
|
+
jobOptions: payload.options || {},
|
|
1058
|
+
name: `Background job worker inline: ${payload.jobName}`,
|
|
1059
|
+
payload
|
|
1058
1060
|
})
|
|
1059
1061
|
}
|
|
1060
1062
|
|