velocious 1.0.377 → 1.0.378
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 +13 -1
- package/build/src/background-jobs/main.d.ts +76 -3
- package/build/src/background-jobs/main.d.ts.map +1 -1
- package/build/src/background-jobs/main.js +263 -44
- package/build/src/background-jobs/store.d.ts +9 -0
- package/build/src/background-jobs/store.d.ts.map +1 -1
- package/build/src/background-jobs/store.js +28 -1
- package/build/src/configuration-types.d.ts +39 -0
- package/build/src/configuration-types.d.ts.map +1 -1
- package/build/src/configuration-types.js +18 -1
- package/build/src/configuration.d.ts.map +1 -1
- package/build/src/configuration.js +10 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1789,7 +1789,8 @@ export default new Configuration({
|
|
|
1789
1789
|
host: "127.0.0.1",
|
|
1790
1790
|
port: 7331,
|
|
1791
1791
|
databaseIdentifier: "default",
|
|
1792
|
-
maxConcurrentInlineJobs: 4
|
|
1792
|
+
maxConcurrentInlineJobs: 4,
|
|
1793
|
+
dispatchStrategy: "beacon"
|
|
1793
1794
|
}
|
|
1794
1795
|
})
|
|
1795
1796
|
```
|
|
@@ -1801,10 +1802,21 @@ VELOCIOUS_BACKGROUND_JOBS_HOST=127.0.0.1
|
|
|
1801
1802
|
VELOCIOUS_BACKGROUND_JOBS_PORT=7331
|
|
1802
1803
|
VELOCIOUS_BACKGROUND_JOBS_DATABASE_IDENTIFIER=default
|
|
1803
1804
|
VELOCIOUS_BACKGROUND_JOBS_MAX_CONCURRENT_INLINE_JOBS=4
|
|
1805
|
+
VELOCIOUS_BACKGROUND_JOBS_DISPATCH_STRATEGY=beacon
|
|
1806
|
+
VELOCIOUS_BACKGROUND_JOBS_POLL_INTERVAL_MS=1000
|
|
1804
1807
|
```
|
|
1805
1808
|
|
|
1806
1809
|
`maxConcurrentInlineJobs` (default: `4`) caps how many `forked: false` jobs a single `background-jobs-worker` process runs in parallel. Concurrency is at the JS event-loop level: every job in flight shares the worker's process and DB connection pool, so the cap should fit the pool, not the CPU count. Forking remains the right tool when you need memory isolation across long-running jobs or want to use more cores.
|
|
1807
1810
|
|
|
1811
|
+
### Dispatch strategy
|
|
1812
|
+
|
|
1813
|
+
`dispatchStrategy` controls how `background-jobs-main` detects new work.
|
|
1814
|
+
|
|
1815
|
+
- `"beacon"` (default): event-driven dispatch. `background-jobs-main` drains the queue when a job is enqueued (directly, or via a [Beacon](docs/beacon.md) broadcast from another process), when a worker comes up or reports ready, and at the exact `scheduled_at_ms` of the next future-scheduled job via a precise `setTimeout`. There is no fixed-interval polling. The `background_jobs` table is the durable log — on (re)connect to Beacon, the dispatcher does a one-shot catch-up drain so anything enqueued while the bus was unreachable is picked up.
|
|
1816
|
+
- `"polling"`: legacy fixed-interval poll. `background-jobs-main` runs `SELECT … FROM background_jobs WHERE status='queued' AND scheduled_at_ms <= now` every `pollIntervalMs` (default `1000`). Use this if you want the previous behavior, or for environments where Beacon is unavailable and you don't want event-driven dispatch.
|
|
1817
|
+
|
|
1818
|
+
Beacon is opt-in for the rest of the framework, but the dispatcher uses event-driven dispatch even when Beacon is not configured — it falls back to direct in-process triggering from the enqueue/handoff paths plus `setTimeout` for scheduled jobs. Configure Beacon when you want cross-process enqueues (e.g. enqueue from an HTTP server process) to wake the main process immediately.
|
|
1819
|
+
|
|
1808
1820
|
## Defining jobs
|
|
1809
1821
|
|
|
1810
1822
|
```js
|
|
@@ -13,6 +13,8 @@ export default class BackgroundJobsMain {
|
|
|
13
13
|
configuration: import("../configuration.js").default;
|
|
14
14
|
host: string;
|
|
15
15
|
port: number;
|
|
16
|
+
dispatchStrategy: import("../configuration-types.js").BackgroundJobsDispatchStrategy;
|
|
17
|
+
pollIntervalMs: number;
|
|
16
18
|
store: BackgroundJobsStore;
|
|
17
19
|
logger: Logger;
|
|
18
20
|
/** @type {Set<JsonSocket>} */
|
|
@@ -22,12 +24,24 @@ export default class BackgroundJobsMain {
|
|
|
22
24
|
/** @type {net.Server | undefined} */
|
|
23
25
|
server: net.Server | undefined;
|
|
24
26
|
/** @type {NodeJS.Timeout | undefined} */
|
|
25
|
-
|
|
27
|
+
_pollTimer: NodeJS.Timeout | undefined;
|
|
28
|
+
/** @type {NodeJS.Timeout | undefined} */
|
|
29
|
+
_scheduledTimer: NodeJS.Timeout | undefined;
|
|
30
|
+
/** @type {NodeJS.Timeout | undefined} */
|
|
31
|
+
_errorRetryTimer: NodeJS.Timeout | undefined;
|
|
26
32
|
/** @type {NodeJS.Timeout | undefined} */
|
|
27
33
|
_orphanTimer: NodeJS.Timeout | undefined;
|
|
28
34
|
/** @type {BackgroundJobsScheduler | undefined} */
|
|
29
35
|
scheduler: BackgroundJobsScheduler | undefined;
|
|
30
|
-
|
|
36
|
+
_draining: boolean;
|
|
37
|
+
_redrainQueued: boolean;
|
|
38
|
+
_stopped: boolean;
|
|
39
|
+
/** @type {(() => void) | undefined} */
|
|
40
|
+
_unsubscribeBeacon: (() => void) | undefined;
|
|
41
|
+
/** @type {((...args: any[]) => void) | undefined} */
|
|
42
|
+
_beaconConnectHandler: ((...args: any[]) => void) | undefined;
|
|
43
|
+
/** @type {import("../beacon/client.js").default | import("../beacon/in-process-client.js").default | undefined} */
|
|
44
|
+
_beaconClient: import("../beacon/client.js").default | import("../beacon/in-process-client.js").default | undefined;
|
|
31
45
|
/**
|
|
32
46
|
* @returns {Promise<void>} - Resolves when listening.
|
|
33
47
|
*/
|
|
@@ -40,6 +54,26 @@ export default class BackgroundJobsMain {
|
|
|
40
54
|
* @returns {number} - Bound port.
|
|
41
55
|
*/
|
|
42
56
|
getPort(): number;
|
|
57
|
+
/**
|
|
58
|
+
* Wires up the dispatch-triggering signal sources for the configured
|
|
59
|
+
* strategy. In `"beacon"` mode (default) this means subscribing to the
|
|
60
|
+
* `velocious-background-jobs-dispatch` channel for cross-process
|
|
61
|
+
* wake-ups, listening for Beacon (re)connects to catch up on missed
|
|
62
|
+
* work, and relying on direct in-process calls from `_handleEnqueue`,
|
|
63
|
+
* `_handleJobComplete`/`Failed`, worker hello/ready, and the
|
|
64
|
+
* scheduled-job `setTimeout`. In `"polling"` mode we restore the
|
|
65
|
+
* legacy fixed-interval poll for users who want the previous behavior.
|
|
66
|
+
* @returns {void}
|
|
67
|
+
*/
|
|
68
|
+
_setupDispatchTriggers(): void;
|
|
69
|
+
/**
|
|
70
|
+
* Publishes a dispatch wake-up on the Beacon channel. No-op in polling
|
|
71
|
+
* mode or when Beacon is not connected; in those cases the direct
|
|
72
|
+
* in-process `_drain()` call in the enqueue/handle paths is sufficient
|
|
73
|
+
* (there are no other processes to notify).
|
|
74
|
+
* @returns {void}
|
|
75
|
+
*/
|
|
76
|
+
_notifyEnqueued(): void;
|
|
43
77
|
/**
|
|
44
78
|
* @param {import("net").Socket} socket - Socket.
|
|
45
79
|
* @returns {void}
|
|
@@ -75,7 +109,46 @@ export default class BackgroundJobsMain {
|
|
|
75
109
|
jsonSocket: JsonSocket;
|
|
76
110
|
message: import("./types.js").BackgroundJobFailedMessage;
|
|
77
111
|
}): Promise<void>;
|
|
78
|
-
|
|
112
|
+
/**
|
|
113
|
+
* Drains all dispatchable jobs to ready workers, then arms the
|
|
114
|
+
* scheduled-job timer for the next future `scheduled_at_ms`. Coalesces
|
|
115
|
+
* concurrent triggers: a wake-up that lands while a drain is in
|
|
116
|
+
* flight just sets a re-drain flag and lets the in-flight drain
|
|
117
|
+
* re-loop after it finishes, so no signal is dropped but no two
|
|
118
|
+
* drains run in parallel.
|
|
119
|
+
*
|
|
120
|
+
* Resilience: in beacon mode this is the sole wake-up path for
|
|
121
|
+
* already-queued work, so a transient DB error during the drain (e.g.
|
|
122
|
+
* `nextAvailableJob()` rejecting) must not strand the queue until the
|
|
123
|
+
* next external signal. On any error we log it and arm a one-shot
|
|
124
|
+
* retry via `_scheduleErrorRetry` using `pollIntervalMs` as the
|
|
125
|
+
* cadence; on success the retry timer is cleared. Polling-mode runs
|
|
126
|
+
* `_drain` from its own interval, so the retry timer is a no-op there.
|
|
127
|
+
* @returns {Promise<void>}
|
|
128
|
+
*/
|
|
129
|
+
_drain(): Promise<void>;
|
|
130
|
+
/**
|
|
131
|
+
* Arms a one-shot `setTimeout` to retry `_drain` after a transient
|
|
132
|
+
* failure. Idempotent — repeated calls while a retry is already
|
|
133
|
+
* pending are no-ops. Polling mode already retries via its own
|
|
134
|
+
* interval, so this is a no-op in that mode.
|
|
135
|
+
* @returns {void}
|
|
136
|
+
*/
|
|
137
|
+
_scheduleErrorRetry(): void;
|
|
138
|
+
/**
|
|
139
|
+
* Inner drain loop: pulls eligible queued jobs and hands them off to
|
|
140
|
+
* ready workers until one of them runs out.
|
|
141
|
+
* @returns {Promise<void>}
|
|
142
|
+
*/
|
|
143
|
+
_drainOnce(): Promise<void>;
|
|
144
|
+
/**
|
|
145
|
+
* Arms a single `setTimeout` for the soonest future-scheduled job's
|
|
146
|
+
* `scheduled_at_ms`. Replaces the second responsibility of the legacy
|
|
147
|
+
* 1-second poll (becoming-eligible scheduled jobs). The timer is
|
|
148
|
+
* idempotently re-armed at the end of every drain.
|
|
149
|
+
* @returns {Promise<void>}
|
|
150
|
+
*/
|
|
151
|
+
_armScheduledTimer(): Promise<void>;
|
|
79
152
|
_sweepOrphans(): Promise<void>;
|
|
80
153
|
}
|
|
81
154
|
import BackgroundJobsStore from "./store.js";
|
|
@@ -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":"AAwBA;IACE;;;;;OAKG;IACH,2CAJG;QAAoD,aAAa,EAAzD,OAAO,qBAAqB,EAAE,OAAO;QACvB,IAAI;QACJ,IAAI;KAC5B,EAmCA;IAjCC,qDAAkC;IAElC,aAA+B;IAC/B,aAAyD;IACzD,qFAA+C;IAC/C,uBAA2C;IAC3C,2BAAoG;IACpG,eAA8B;IAC9B,8BAA8B;IAC9B,SADW,GAAG,CAAC,UAAU,CAAC,CACF;IACxB,8BAA8B;IAC9B,cADW,GAAG,CAAC,UAAU,CAAC,CACG;IAC7B,qCAAqC;IACrC,QADW,GAAG,CAAC,MAAM,GAAG,SAAS,CACV;IACvB,yCAAyC;IACzC,YADW,MAAM,CAAC,OAAO,GAAG,SAAS,CACV;IAC3B,yCAAyC;IACzC,iBADW,MAAM,CAAC,OAAO,GAAG,SAAS,CACL;IAChC,yCAAyC;IACzC,kBADW,MAAM,CAAC,OAAO,GAAG,SAAS,CACJ;IACjC,yCAAyC;IACzC,cADW,MAAM,CAAC,OAAO,GAAG,SAAS,CACR;IAC7B,kDAAkD;IAClD,WADW,uBAAuB,GAAG,SAAS,CACpB;IAC1B,mBAAsB;IACtB,wBAA2B;IAC3B,kBAAqB;IACrB,uCAAuC;IACvC,oBADW,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS,CACA;IACnC,qDAAqD;IACrD,uBADW,CAAC,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,CAAC,GAAG,SAAS,CACX;IACtC,mHAAmH;IACnH,eADW,OAAO,qBAAqB,EAAE,OAAO,GAAG,OAAO,gCAAgC,EAAE,OAAO,GAAG,SAAS,CACjF;IAGhC;;OAEG;IACH,SAFa,OAAO,CAAC,IAAI,CAAC,CAoDzB;IAED;;OAEG;IACH,QAFa,OAAO,CAAC,IAAI,CAAC,CAqCzB;IAED;;OAEG;IACH,WAFa,MAAM,CAIlB;IAED;;;;;;;;;;OAUG;IACH,0BAFa,IAAI,CA2BhB;IAED;;;;;;OAMG;IACH,mBAFa,IAAI,CAiBhB;IAED;;;OAGG;IACH,0BAHW,OAAO,KAAK,EAAE,MAAM,GAClB,IAAI,CA+DhB;IAED;;;;;OAKG;IACH,wCAJG;QAAyB,UAAU,EAA3B,UAAU;QAC6C,OAAO,EAA9D,OAAO,YAAY,EAAE,2BAA2B;KACxD,GAAU,OAAO,CAAC,IAAI,CAAC,CAiBzB;IAED;;;;;OAKG;IACH,4CAJG;QAAyB,UAAU,EAA3B,UAAU;QAC8C,OAAO,EAA/D,OAAO,YAAY,EAAE,4BAA4B;KACzD,GAAU,OAAO,CAAC,IAAI,CAAC,CAczB;IAED;;;;;OAKG;IACH,0CAJG;QAAyB,UAAU,EAA3B,UAAU;QAC4C,OAAO,EAA7D,OAAO,YAAY,EAAE,0BAA0B;KACvD,GAAU,OAAO,CAAC,IAAI,CAAC,CAmBzB;IAED;;;;;;;;;;;;;;;;OAgBG;IACH,UAFa,OAAO,CAAC,IAAI,CAAC,CA+CzB;IAED;;;;;;OAMG;IACH,uBAFa,IAAI,CAWhB;IAED;;;;OAIG;IACH,cAFa,OAAO,CAAC,IAAI,CAAC,CAkCzB;IAED;;;;;;OAMG;IACH,sBAFa,OAAO,CAAC,IAAI,CAAC,CAoBzB;IAED,+BAcC;CACF;gCA5gB+B,YAAY;mBACzB,cAAc;uBAHV,kBAAkB;gBADzB,KAAK;oCAEe,gBAAgB"}
|