velocious 1.0.526 → 1.0.528
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 +12 -0
- package/build/background-jobs/main.js +16 -1
- package/build/background-jobs/store.js +16 -1
- package/build/background-jobs/types.js +1 -0
- package/build/src/background-jobs/main.d.ts.map +1 -1
- package/build/src/background-jobs/main.js +15 -2
- package/build/src/background-jobs/store.d.ts +7 -0
- package/build/src/background-jobs/store.d.ts.map +1 -1
- package/build/src/background-jobs/store.js +17 -2
- package/build/src/background-jobs/types.d.ts +5 -0
- package/build/src/background-jobs/types.d.ts.map +1 -1
- package/build/src/background-jobs/types.js +2 -1
- package/package.json +1 -1
- package/src/background-jobs/main.js +16 -1
- package/src/background-jobs/store.js +16 -1
- package/src/background-jobs/types.js +1 -0
package/README.md
CHANGED
|
@@ -25,6 +25,7 @@
|
|
|
25
25
|
* Cross-process broadcast bus for `broadcastToChannel` via `velocious beacon`, including background job runner processes (see [docs/beacon.md](docs/beacon.md))
|
|
26
26
|
* Configurable HTTP server worker handlers plus backpressured, descriptor-only file responses with completion callbacks (see [docs/http-server.md](docs/http-server.md))
|
|
27
27
|
* Background jobs with failure events for production reporting (see [docs/background-jobs.md](docs/background-jobs.md))
|
|
28
|
+
* Durable one-off background-job scheduling with exact epoch timestamps (see [docs/scheduled-background-job-enqueue.md](docs/scheduled-background-job-enqueue.md))
|
|
28
29
|
* Rails-style request and database query logging (see [docs/logging.md](docs/logging.md))
|
|
29
30
|
* EJS-backed mailers with delivery, queueing, and payload rendering support (see [docs/mailers.md](docs/mailers.md))
|
|
30
31
|
* Trusted reverse proxy handling for `request.remoteAddress()` (see [docs/trusted-proxies.md](docs/trusted-proxies.md))
|
|
@@ -2052,6 +2053,17 @@ await MyJob.performLaterWithOptions({
|
|
|
2052
2053
|
})
|
|
2053
2054
|
```
|
|
2054
2055
|
|
|
2056
|
+
[Schedule a one-off job](docs/scheduled-background-job-enqueue.md) for a specific epoch timestamp in milliseconds:
|
|
2057
|
+
|
|
2058
|
+
```js
|
|
2059
|
+
await MyJob.performLaterWithOptions({
|
|
2060
|
+
args: ["a", "b"],
|
|
2061
|
+
options: {scheduledAtMs: Date.now() + 2 * 60 * 60 * 1000}
|
|
2062
|
+
})
|
|
2063
|
+
```
|
|
2064
|
+
|
|
2065
|
+
Until `scheduledAtMs` is reached, the job remains queued but is not eligible for dispatch. The event-driven dispatcher arms its timer for the earliest future job and wakes at that timestamp. Omitting `scheduledAtMs` keeps the immediate-enqueue behavior.
|
|
2066
|
+
|
|
2055
2067
|
The older `options: {forked: false}` form is still accepted as an alias for inline execution, and `options: {forked: true}` maps to forked execution. To use the previous spawned CLI runner behavior explicitly, pass `options: {executionMode: "spawned"}`.
|
|
2056
2068
|
|
|
2057
2069
|
Inline jobs share the worker process and run concurrently up to `maxConcurrentInlineJobs`, so a single slow inline job no longer blocks the queue. A single worker can also override the configured cap explicitly:
|
|
@@ -6,6 +6,7 @@ import BackgroundJobsScheduler from "./scheduler.js"
|
|
|
6
6
|
import BackgroundJobsStore from "./store.js"
|
|
7
7
|
import Logger from "../logger.js"
|
|
8
8
|
import PruneTerminalBackgroundJobsJob from "../jobs/prune-terminal-background-jobs.js"
|
|
9
|
+
import VelociousError from "../velocious-error.js"
|
|
9
10
|
|
|
10
11
|
/**
|
|
11
12
|
* Channel used by `background-jobs-main` to coordinate dispatch wake-ups
|
|
@@ -683,7 +684,21 @@ export default class BackgroundJobsMain {
|
|
|
683
684
|
this._notifyEnqueued()
|
|
684
685
|
await this._drain()
|
|
685
686
|
} catch (error) {
|
|
686
|
-
|
|
687
|
+
if (error instanceof VelociousError && error.safeToExpose) {
|
|
688
|
+
jsonSocket.send({type: "enqueue-error", error: error.message})
|
|
689
|
+
return
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
const normalizedError = error instanceof Error ? error : new Error(String(error))
|
|
693
|
+
const payload = {
|
|
694
|
+
context: {jobName: message.jobName, stage: "background-job-enqueue"},
|
|
695
|
+
error: normalizedError
|
|
696
|
+
}
|
|
697
|
+
const errorEvents = this.configuration.getErrorEvents()
|
|
698
|
+
|
|
699
|
+
this.logger.error(() => ["Failed to enqueue background job:", normalizedError])
|
|
700
|
+
errorEvents.emit("framework-error", payload)
|
|
701
|
+
errorEvents.emit("all-error", {...payload, errorType: "framework-error"})
|
|
687
702
|
jsonSocket.send({type: "enqueue-error", error: "Failed to enqueue job"})
|
|
688
703
|
}
|
|
689
704
|
}
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
import {randomUUID} from "crypto"
|
|
4
4
|
import Logger from "../logger.js"
|
|
5
5
|
import TableData from "../database/table-data/index.js"
|
|
6
|
+
import VelociousError from "../velocious-error.js"
|
|
6
7
|
import BackgroundJobRecord from "./job-record.js"
|
|
7
8
|
import normalizeBackgroundJobError from "./normalize-error.js"
|
|
8
9
|
|
|
@@ -99,6 +100,7 @@ export default class BackgroundJobsStore {
|
|
|
99
100
|
const now = Date.now()
|
|
100
101
|
const executionMode = this._normalizeExecutionMode(options)
|
|
101
102
|
const maxRetries = this._normalizeMaxRetries(options?.maxRetries)
|
|
103
|
+
const scheduledAtMs = this._normalizeScheduledAtMs(options?.scheduledAtMs, now)
|
|
102
104
|
const argsJson = JSON.stringify(args || [])
|
|
103
105
|
const queue = this._normalizeQueue(options)
|
|
104
106
|
const concurrency = this._resolveConcurrency(options, queue)
|
|
@@ -141,7 +143,7 @@ export default class BackgroundJobsStore {
|
|
|
141
143
|
max_retries: maxRetries,
|
|
142
144
|
attempts: 0,
|
|
143
145
|
status: "queued",
|
|
144
|
-
scheduled_at_ms:
|
|
146
|
+
scheduled_at_ms: scheduledAtMs,
|
|
145
147
|
created_at_ms: now,
|
|
146
148
|
concurrency_key: concurrency?.concurrencyKey || null,
|
|
147
149
|
max_concurrency: concurrency?.maxConcurrency || null
|
|
@@ -726,6 +728,19 @@ export default class BackgroundJobsStore {
|
|
|
726
728
|
return DEFAULT_MAX_RETRIES
|
|
727
729
|
}
|
|
728
730
|
|
|
731
|
+
/**
|
|
732
|
+
* Runs normalize scheduled at ms.
|
|
733
|
+
* @param {number | undefined} scheduledAtMs - Requested dispatch timestamp.
|
|
734
|
+
* @param {number} defaultScheduledAtMs - Default dispatch timestamp.
|
|
735
|
+
* @returns {number} - Dispatch timestamp.
|
|
736
|
+
*/
|
|
737
|
+
_normalizeScheduledAtMs(scheduledAtMs, defaultScheduledAtMs) {
|
|
738
|
+
if (scheduledAtMs === undefined) return defaultScheduledAtMs
|
|
739
|
+
if (Number.isSafeInteger(scheduledAtMs) && scheduledAtMs >= 0) return scheduledAtMs
|
|
740
|
+
|
|
741
|
+
throw VelociousError.safe("background job scheduledAtMs must be a non-negative safe integer")
|
|
742
|
+
}
|
|
743
|
+
|
|
729
744
|
async _ensureSchema() {
|
|
730
745
|
await this._withDb(async (db) => {
|
|
731
746
|
await this._ensureMigrationsTable(db)
|
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
* @property {string} [concurrencyKey] - Opaque non-empty key used to share a concurrency cap. Overrides any queue-derived cap.
|
|
18
18
|
* @property {number} [maxConcurrency] - Positive integer cap; must be paired with `concurrencyKey`.
|
|
19
19
|
* @property {boolean} [deduplicateWhileQueued] - When true (requires `concurrencyKey`), skip the enqueue if a still-queued job with the same `concurrencyKey` already exists, returning that job's id. Keeps an interval-scheduled recurring job (e.g. retention pruning) from piling up redundant queued rows when it runs slower than its interval or no worker is free.
|
|
20
|
+
* @property {number} [scheduledAtMs] - Epoch timestamp in milliseconds when the job becomes eligible for dispatch. Defaults to enqueue time.
|
|
20
21
|
*/
|
|
21
22
|
/**
|
|
22
23
|
* @typedef {object} BackgroundJobPayload
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../../src/background-jobs/main.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../../src/background-jobs/main.js"],"names":[],"mappings":"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"}
|