velocious 1.0.532 → 1.0.534

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.
Files changed (42) hide show
  1. package/README.md +5 -3
  2. package/build/background-jobs/main.js +1 -2
  3. package/build/background-jobs/store.js +161 -101
  4. package/build/background-jobs/types.js +1 -3
  5. package/build/background-jobs/web/controller.js +0 -1
  6. package/build/background-jobs/worker.js +2 -7
  7. package/build/database/migration/index.js +20 -0
  8. package/build/database/migrator.js +5 -0
  9. package/build/environment-handlers/base.js +14 -0
  10. package/build/environment-handlers/node.js +23 -0
  11. package/build/src/background-jobs/main.d.ts.map +1 -1
  12. package/build/src/background-jobs/main.js +2 -3
  13. package/build/src/background-jobs/store.d.ts +44 -24
  14. package/build/src/background-jobs/store.d.ts.map +1 -1
  15. package/build/src/background-jobs/store.js +144 -105
  16. package/build/src/background-jobs/types.d.ts +2 -12
  17. package/build/src/background-jobs/types.d.ts.map +1 -1
  18. package/build/src/background-jobs/types.js +2 -4
  19. package/build/src/background-jobs/web/controller.d.ts.map +1 -1
  20. package/build/src/background-jobs/web/controller.js +1 -2
  21. package/build/src/background-jobs/worker.d.ts.map +1 -1
  22. package/build/src/background-jobs/worker.js +3 -10
  23. package/build/src/database/migration/index.d.ts +7 -0
  24. package/build/src/database/migration/index.d.ts.map +1 -1
  25. package/build/src/database/migration/index.js +18 -1
  26. package/build/src/database/migrator.d.ts.map +1 -1
  27. package/build/src/database/migrator.js +6 -1
  28. package/build/src/environment-handlers/base.d.ts +13 -0
  29. package/build/src/environment-handlers/base.d.ts.map +1 -1
  30. package/build/src/environment-handlers/base.js +14 -1
  31. package/build/src/environment-handlers/node.d.ts.map +1 -1
  32. package/build/src/environment-handlers/node.js +22 -1
  33. package/package.json +1 -1
  34. package/src/background-jobs/main.js +1 -2
  35. package/src/background-jobs/store.js +161 -101
  36. package/src/background-jobs/types.js +1 -3
  37. package/src/background-jobs/web/controller.js +0 -1
  38. package/src/background-jobs/worker.js +2 -7
  39. package/src/database/migration/index.js +20 -0
  40. package/src/database/migrator.js +5 -0
  41. package/src/environment-handlers/base.js +14 -0
  42. package/src/environment-handlers/node.js +23 -0
package/README.md CHANGED
@@ -1102,6 +1102,8 @@ export default class CreateEvents extends Migration {
1102
1102
  }
1103
1103
  ```
1104
1104
 
1105
+ Migrations that must be rerunnable can guard changes with `tableExists(...)`, `columnExists(table, column)` and `indexExists(table, index)` — a missing table yields `false` rather than throwing. See [docs/database-migrations.md](docs/database-migrations.md#guarding-schema-changes-in-rerunnable-migrations).
1106
+
1105
1107
  ## Run migrations from the command line
1106
1108
 
1107
1109
  ```bash
@@ -2007,9 +2009,9 @@ VELOCIOUS_BACKGROUND_JOBS_JOB_TIMEOUT_MS=5400000
2007
2009
 
2008
2010
  `VELOCIOUS_BACKGROUND_JOBS_WORKER_SHUTDOWN_TIMEOUT_MS` (default: `indefinite`) bounds how long a `background-jobs-worker` waits for in-flight jobs on `SIGTERM`/`SIGINT` before terminating any forked or spawned child runners still running, so they are not orphaned across a deploy. The default waits for jobs to finish and never interrupts a running job; set a positive number of milliseconds for a finite cap (keep it shorter than your process supervisor's graceful-stop window so the worker reaps its own runners first). See [docs/background-jobs.md](docs/background-jobs.md#worker-shutdown-and-process-job-draining).
2009
2011
 
2010
- `maxConcurrentInlineJobs` (default: `4`) caps how many `executionMode: "inline"` 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. The older `forked: false` option still maps to inline mode.
2012
+ `maxConcurrentInlineJobs` (default: `4`) caps how many `executionMode: "inline"` 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; select it with `executionMode: "forked"`.
2011
2013
 
2012
- New jobs default to `executionMode: "pooled"`: a worker runs them in warm, reusable Node child runners. `pooledRunnerCount` (default: `4`) bounds this independent per-worker pool, and `pooledRunnerConcurrency` (default: `1`) sets how many jobs each child runs at once on its own event loop, so total pooled capacity is `pooledRunnerCount × pooledRunnerConcurrency` — raise concurrency for I/O-bound jobs to get high throughput from a bounded, isolated set of processes. `pooledRunnerCount`, `pooledRunnerConcurrency`, and `pooledRunnerMaxJobs` must be finite positive integers; the RSS and lifetime limits must be finite positive numbers. A child is recycled after an acknowledged job when it reaches `pooledRunnerMaxJobs` (default: `100`), `pooledRunnerMaxRssBytes` (default: `536870912`, or 512 MiB), or `pooledRunnerMaxLifetimeMs` (default: `3600000`, or one hour). Pooled rows remain readable by older mains during rolling upgrades and run there with legacy one-shot fork behavior. `forked: true` remains an explicit alias for `"forked"`; `forked: false` remains inline. See [execution modes and pooled runners](docs/background-jobs.md#execution-modes-and-pooled-runners).
2014
+ New jobs default to `executionMode: "pooled"`: a worker runs them in warm, reusable Node child runners. `pooledRunnerCount` (default: `4`) bounds this independent per-worker pool, and `pooledRunnerConcurrency` (default: `1`) sets how many jobs each child runs at once on its own event loop, so total pooled capacity is `pooledRunnerCount × pooledRunnerConcurrency` — raise concurrency for I/O-bound jobs to get high throughput from a bounded, isolated set of processes. `pooledRunnerCount`, `pooledRunnerConcurrency`, and `pooledRunnerMaxJobs` must be finite positive integers; the RSS and lifetime limits must be finite positive numbers. A child is recycled after an acknowledged job when it reaches `pooledRunnerMaxJobs` (default: `100`), `pooledRunnerMaxRssBytes` (default: `536870912`, or 512 MiB), or `pooledRunnerMaxLifetimeMs` (default: `3600000`, or one hour). `execution_mode` is the single source of truth for a job's runtime pooled rows persist as `execution_mode = "pooled"` directly. See [execution modes and pooled runners](docs/background-jobs.md#execution-modes-and-pooled-runners).
2013
2015
 
2014
2016
  `maxConcurrentForkedJobs` (default: `4`) caps how many out-of-process `executionMode: "forked"` or `executionMode: "spawned"` jobs one worker may keep in flight. Forked jobs use `child_process.fork()` with an attached IPC channel. After the main process acknowledges their durable status report, forked and spawned one-shot runners exit without waiting for graceful Beacon/database teardown; the OS closes their process-owned resources. A missing or rejected status acknowledgement makes the runner exit as failed instead of reporting clean success. Spawned jobs use the legacy `background-jobs-runner` CLI process via `child_process.spawn()` and are only for callers that intentionally want that spawned behavior.
2015
2017
 
@@ -2075,7 +2077,7 @@ await MyJob.performLaterWithOptions({
2075
2077
 
2076
2078
  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.
2077
2079
 
2078
- 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"}`.
2080
+ Select a non-default runtime explicitly with `options: {executionMode: "inline" | "forked" | "spawned"}`.
2079
2081
 
2080
2082
  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:
2081
2083
 
@@ -1142,8 +1142,7 @@ export default class BackgroundJobsMain {
1142
1142
  workerId: worker.workerId,
1143
1143
  handedOffAtMs: handoff.handedOffAtMs,
1144
1144
  options: {
1145
- executionMode: job.executionMode,
1146
- forked: job.forked
1145
+ executionMode: job.executionMode
1147
1146
  }
1148
1147
  }
1149
1148
  })
@@ -11,6 +11,16 @@ const MIGRATIONS_TABLE = "velocious_internal_migrations"
11
11
  const MIGRATION_SCOPE = "background_jobs"
12
12
  const MIGRATION_VERSION = "20250215000000"
13
13
  const EXECUTION_MODE_BACKFILL_MIGRATION_VERSION = "20260607131010"
14
+ // Drops the redundant legacy `forked` boolean column and rewrites pooled rows to
15
+ // persist `execution_mode = "pooled"` directly (retiring the pooled-as-forked
16
+ // handoff-marker workaround), leaving `execution_mode` as the single source of
17
+ // truth for a job's runtime.
18
+ const DROP_FORKED_COLUMN_MIGRATION_VERSION = "20260719000000"
19
+ // Legacy marker prefix used by rows written before this migration: pooled jobs
20
+ // used to persist as `execution_mode = "forked"` plus a `velocious-pooled:*`
21
+ // handoff id. Retained only to detect and convert those rows in the migration.
22
+ const LEGACY_POOLED_HANDOFF_ID_PREFIX = "velocious-pooled:"
23
+ const LEGACY_POOLED_QUEUED_HANDOFF_ID = `${LEGACY_POOLED_HANDOFF_ID_PREFIX}queued`
14
24
  const JOBS_TABLE = "background_jobs"
15
25
  const CONCURRENCY_TABLE = "background_job_concurrency"
16
26
  const DEFAULT_MAX_RETRIES = 10
@@ -25,18 +35,6 @@ const EXECUTION_MODES = ["inline", "forked", "pooled", "spawned"]
25
35
  * process — the same isolation as forked without paying a fresh process per job.
26
36
  * @type {import("./types.js").BackgroundJobExecutionMode} */
27
37
  const DEFAULT_EXECUTION_MODE = "pooled"
28
- /**
29
- * Execution mode a legacy `forked = true` row (persisted before the
30
- * `execution_mode` column existed) backfills to. It must stay `"forked"` so an
31
- * upgrade never silently reinterprets already-persisted forked jobs as pooled —
32
- * distinct from {@link DEFAULT_EXECUTION_MODE}, which only governs new enqueues.
33
- * @type {import("./types.js").BackgroundJobExecutionMode} */
34
- const LEGACY_FORKED_EXECUTION_MODE = "forked"
35
- // Pooled jobs persist with the legacy-safe `forked` mode so a pre-pool main can
36
- // deserialize and run them during a rolling upgrade. Old versions ignore the
37
- // nullable handoff id on queued rows, making it a backward-compatible marker.
38
- const POOLED_HANDOFF_ID_PREFIX = "velocious-pooled:"
39
- const POOLED_QUEUED_HANDOFF_ID = `${POOLED_HANDOFF_ID_PREFIX}queued`
40
38
  const DEFAULT_QUEUE = "default"
41
39
  // Queue-derived durable concurrency keys are namespaced so they can't collide
42
40
  // with explicit caller-supplied concurrencyKeys.
@@ -102,6 +100,27 @@ export default class BackgroundJobsStore {
102
100
  }
103
101
  }
104
102
 
103
+ /**
104
+ * Ensures the background-jobs schema (tables + columns) exists on the configured
105
+ * database, without initializing the runtime model. Lets `db:migrate` create the
106
+ * framework's own schema deterministically alongside app migrations — and capture
107
+ * it in the dumped structure SQL — instead of it only appearing once a store boots.
108
+ * Idempotent: reuses the same `_ensureSchema` the runtime store uses, which skips
109
+ * work already applied (tracked in `velocious_internal_migrations`).
110
+ * @param {import("../database/drivers/base.js").default} [db] - Reuse an already
111
+ * checked-out connection (e.g. the one `db:migrate` holds) rather than opening a
112
+ * nested checkout that would deadlock a single-connection pool.
113
+ * @returns {Promise<void>} - Resolves when the schema is present.
114
+ */
115
+ async ensureSchema(db) {
116
+ // When a connection is handed in (the db:migrate path), the caller already owns
117
+ // the active configuration + connection context; calling setCurrent() here would
118
+ // clobber it (e.g. the browser test runner juggles multiple configurations).
119
+ if (!db) this.configuration.setCurrent()
120
+
121
+ await this._ensureSchema(db)
122
+ }
123
+
105
124
  /**
106
125
  * Runs enqueue.
107
126
  * @param {object} args - Options.
@@ -154,8 +173,7 @@ export default class BackgroundJobsStore {
154
173
  id: jobId,
155
174
  job_name: jobName,
156
175
  args_json: argsJson,
157
- forked: executionMode !== "inline",
158
- execution_mode: executionMode === "pooled" ? LEGACY_FORKED_EXECUTION_MODE : executionMode,
176
+ execution_mode: executionMode,
159
177
  queue,
160
178
  max_retries: maxRetries,
161
179
  attempts: 0,
@@ -164,7 +182,7 @@ export default class BackgroundJobsStore {
164
182
  created_at_ms: now,
165
183
  concurrency_key: concurrency?.concurrencyKey || null,
166
184
  max_concurrency: concurrency?.maxConcurrency || null,
167
- handoff_id: executionMode === "pooled" ? POOLED_QUEUED_HANDOFF_ID : null
185
+ handoff_id: null
168
186
  }
169
187
  })
170
188
  })
@@ -175,7 +193,6 @@ export default class BackgroundJobsStore {
175
193
  /**
176
194
  * Runs next available job.
177
195
  * @param {object} [args] - Options.
178
- * @param {boolean} [args.forked] - Compatibility filter for non-inline vs inline jobs.
179
196
  * @param {import("./types.js").BackgroundJobExecutionMode | import("./types.js").BackgroundJobExecutionMode[]} [args.executionMode] - Execution mode or modes to match.
180
197
  * @returns {Promise<import("./types.js").BackgroundJobRow | null>} - Next job.
181
198
  */
@@ -186,7 +203,6 @@ export default class BackgroundJobsStore {
186
203
  return await this._nextQueuedJob({
187
204
  db,
188
205
  scheduledAtOperator: "<=",
189
- forked: args.forked,
190
206
  executionMode: args.executionMode
191
207
  })
192
208
  })
@@ -213,11 +229,10 @@ export default class BackgroundJobsStore {
213
229
  * @param {object} args - Options.
214
230
  * @param {import("../database/drivers/base.js").default} args.db - Database connection.
215
231
  * @param {"<=" | ">"} args.scheduledAtOperator - Scheduled timestamp operator.
216
- * @param {boolean} [args.forked] - Compatibility filter for non-inline vs inline jobs.
217
232
  * @param {import("./types.js").BackgroundJobExecutionMode | import("./types.js").BackgroundJobExecutionMode[]} [args.executionMode] - Execution mode or modes to match.
218
233
  * @returns {Promise<import("./types.js").BackgroundJobRow | null>} - Next matching queued job.
219
234
  */
220
- async _nextQueuedJob({db, scheduledAtOperator, forked, executionMode}) {
235
+ async _nextQueuedJob({db, scheduledAtOperator, executionMode}) {
221
236
  const now = Date.now()
222
237
  let query = db
223
238
  .newQuery()
@@ -236,9 +251,6 @@ export default class BackgroundJobsStore {
236
251
  )
237
252
  }
238
253
 
239
- if (typeof forked === "boolean") {
240
- query = query.where({forked})
241
- }
242
254
  if (executionMode) query = this._whereExecutionMode({db, executionMode, query})
243
255
 
244
256
  if (scheduledAtOperator === "<=") {
@@ -420,9 +432,7 @@ export default class BackgroundJobsStore {
420
432
  const queuedJob = await this._getJobRowById(db, jobId)
421
433
  if (!queuedJob || queuedJob.status !== "queued") return null
422
434
  if (queuedJob.concurrencyKey && !(await this._reserveConcurrency(db, queuedJob.concurrencyKey))) return null
423
- const handoffId = queuedJob.executionMode === "pooled"
424
- ? `${POOLED_HANDOFF_ID_PREFIX}${randomUUID()}`
425
- : randomUUID()
435
+ const handoffId = randomUUID()
426
436
 
427
437
  const affectedRows = await this._updateAffectedRows(db, {
428
438
  tableName: JOBS_TABLE,
@@ -496,7 +506,7 @@ export default class BackgroundJobsStore {
496
506
  status: "queued",
497
507
  scheduled_at_ms: Date.now(),
498
508
  handed_off_at_ms: null,
499
- handoff_id: job.executionMode === "pooled" ? POOLED_QUEUED_HANDOFF_ID : null,
509
+ handoff_id: null,
500
510
  worker_id: null
501
511
  },
502
512
  conditions: {handoff_id: handoffId, id: jobId, status: "handed_off"}
@@ -757,35 +767,59 @@ export default class BackgroundJobsStore {
757
767
  throw VelociousError.safe("background job scheduledAtMs must be a non-negative safe integer")
758
768
  }
759
769
 
760
- async _ensureSchema() {
761
- await this._withDb(async (db) => {
762
- await this._ensureMigrationsTable(db)
763
-
764
- const alreadyApplied = await this._hasMigration(db)
765
-
766
- // Even when the migration row is present, the jobs table itself can have
767
- // been dropped underneath us by a transaction rollback in another caller
768
- // (DDL is transactional on SQLite/MSSQL). Verify the table physically
769
- // exists and recreate it when missing rather than trusting the migration
770
- // row alone, otherwise later callers fail with "no such table".
771
- if (alreadyApplied && await db.tableExists(JOBS_TABLE)) {
772
- await this._ensureJobsTableColumns(db)
773
- await this._ensureConcurrencyTable(db)
774
- await this._reconcileQueueConcurrency(db)
775
- await this._reconcileConcurrency(db)
776
- return
777
- }
770
+ /**
771
+ * Ensures the background-jobs schema exists, reusing a caller-held connection when
772
+ * one is given rather than checking out its own.
773
+ * @param {import("../database/drivers/base.js").default} [existingDb] - Reuse an
774
+ * already-checked-out connection (e.g. the one `db:migrate` holds) instead of
775
+ * checking out a nested one — the nested checkout would deadlock a database
776
+ * whose pool is capped at a single connection already held by the caller.
777
+ * @returns {Promise<void>} - Resolves when the schema is present.
778
+ */
779
+ async _ensureSchema(existingDb) {
780
+ if (existingDb) {
781
+ await this._applySchema(existingDb)
778
782
 
779
- await this._applyMigrations(db)
783
+ return
784
+ }
785
+
786
+ await this._withDb((db) => this._applySchema(db))
787
+ }
788
+
789
+ /**
790
+ * Creates or upgrades the background-jobs tables, columns and concurrency rows on
791
+ * the given connection.
792
+ * @param {import("../database/drivers/base.js").default} db - Database connection.
793
+ * @returns {Promise<void>} - Resolves when the schema is present.
794
+ */
795
+ async _applySchema(db) {
796
+ await this._ensureMigrationsTable(db)
797
+
798
+ const alreadyApplied = await this._hasMigration(db)
799
+
800
+ // Even when the migration row is present, the jobs table itself can have
801
+ // been dropped underneath us by a transaction rollback in another caller
802
+ // (DDL is transactional on SQLite/MSSQL). Verify the table physically
803
+ // exists and recreate it when missing rather than trusting the migration
804
+ // row alone, otherwise later callers fail with "no such table".
805
+ if (alreadyApplied && await db.tableExists(JOBS_TABLE)) {
780
806
  await this._ensureJobsTableColumns(db)
781
807
  await this._ensureConcurrencyTable(db)
782
808
  await this._reconcileQueueConcurrency(db)
783
809
  await this._reconcileConcurrency(db)
784
810
 
785
- if (alreadyApplied) return
811
+ return
812
+ }
786
813
 
787
- await this._recordMigration(db, MIGRATION_VERSION)
788
- })
814
+ await this._applyMigrations(db)
815
+ await this._ensureJobsTableColumns(db)
816
+ await this._ensureConcurrencyTable(db)
817
+ await this._reconcileQueueConcurrency(db)
818
+ await this._reconcileConcurrency(db)
819
+
820
+ if (alreadyApplied) return
821
+
822
+ await this._recordMigration(db, MIGRATION_VERSION)
789
823
  }
790
824
 
791
825
  /**
@@ -842,7 +876,6 @@ export default class BackgroundJobsStore {
842
876
  table.string("id", {primaryKey: true})
843
877
  table.string("job_name", {null: false, index: true})
844
878
  table.text("args_json", {null: false})
845
- table.boolean("forked", {null: false})
846
879
  table.string("execution_mode", {null: false})
847
880
  table.string("queue", {null: true, index: true})
848
881
  table.integer("max_retries", {null: false})
@@ -916,6 +949,7 @@ export default class BackgroundJobsStore {
916
949
  }
917
950
 
918
951
  await this._backfillExecutionModesOnce(db)
952
+ await this._dropForkedColumnOnce(db)
919
953
 
920
954
  const lockName = `${MIGRATION_SCOPE}:concurrency_columns`
921
955
  const acquired = await db.acquireAdvisoryLock(lockName)
@@ -1001,12 +1035,20 @@ export default class BackgroundJobsStore {
1001
1035
  try {
1002
1036
  if (await this._hasMigration(db, migrationVersion)) return
1003
1037
 
1038
+ // A table created after the `forked` column was dropped has nothing to
1039
+ // backfill from; record the migration so it is not re-attempted.
1040
+ db.clearSchemaCache()
1041
+ if (!(await (await db.getTableByNameOrFail(JOBS_TABLE)).getColumnByName("forked"))) {
1042
+ await this._recordMigration(db, migrationVersion)
1043
+ return
1044
+ }
1045
+
1004
1046
  const tableNameSql = db.quoteTable(JOBS_TABLE)
1005
1047
  const forkedColumnSql = db.quoteColumn("forked")
1006
1048
  const executionModeColumnSql = db.quoteColumn("execution_mode")
1007
1049
 
1008
1050
  await db.query(
1009
- `UPDATE ${tableNameSql} SET ${executionModeColumnSql} = ${db.quote(LEGACY_FORKED_EXECUTION_MODE)} ` +
1051
+ `UPDATE ${tableNameSql} SET ${executionModeColumnSql} = ${db.quote("forked")} ` +
1010
1052
  `WHERE ${forkedColumnSql} = ${db.quote(true)} AND ${executionModeColumnSql} IS NULL`
1011
1053
  )
1012
1054
  await db.query(
@@ -1020,6 +1062,60 @@ export default class BackgroundJobsStore {
1020
1062
  }
1021
1063
  }
1022
1064
 
1065
+ /**
1066
+ * Rewrites pre-existing pooled rows (persisted as `execution_mode = "forked"`
1067
+ * plus a `velocious-pooled:*` handoff marker) to `execution_mode = "pooled"`,
1068
+ * clears the queued marker, then drops the now-redundant `forked` column so
1069
+ * `execution_mode` is the single source of truth. Runs once, guarded by the
1070
+ * migration ledger and a per-key advisory lock; a fresh table (created without
1071
+ * the column) short-circuits.
1072
+ * @param {import("../database/drivers/base.js").default} db - Database connection.
1073
+ * @returns {Promise<void>} - Resolves when complete.
1074
+ */
1075
+ async _dropForkedColumnOnce(db) {
1076
+ const migrationVersion = DROP_FORKED_COLUMN_MIGRATION_VERSION
1077
+ const migrationKey = this._migrationKey(migrationVersion)
1078
+
1079
+ if (await this._hasMigration(db, migrationVersion)) return
1080
+
1081
+ await db.acquireAdvisoryLock(migrationKey)
1082
+
1083
+ try {
1084
+ if (await this._hasMigration(db, migrationVersion)) return
1085
+
1086
+ db.clearSchemaCache()
1087
+
1088
+ if (await (await db.getTableByNameOrFail(JOBS_TABLE)).getColumnByName("forked")) {
1089
+ const tableNameSql = db.quoteTable(JOBS_TABLE)
1090
+ const executionModeColumnSql = db.quoteColumn("execution_mode")
1091
+ const handoffIdColumnSql = db.quoteColumn("handoff_id")
1092
+
1093
+ // Pooled rows used to persist as execution_mode "forked" + a pooled handoff
1094
+ // marker; recover their real mode before the marker is cleared.
1095
+ await db.query(
1096
+ `UPDATE ${tableNameSql} SET ${executionModeColumnSql} = ${db.quote("pooled")} ` +
1097
+ `WHERE ${executionModeColumnSql} = ${db.quote("forked")} ` +
1098
+ `AND ${handoffIdColumnSql} LIKE ${db.quote(`${LEGACY_POOLED_HANDOFF_ID_PREFIX}%`)}`
1099
+ )
1100
+ // The queued-pooled marker was a sentinel, not a real lease; clear it.
1101
+ await db.query(
1102
+ `UPDATE ${tableNameSql} SET ${handoffIdColumnSql} = NULL ` +
1103
+ `WHERE ${handoffIdColumnSql} = ${db.quote(LEGACY_POOLED_QUEUED_HANDOFF_ID)}`
1104
+ )
1105
+
1106
+ const dropForked = new TableData(JOBS_TABLE)
1107
+ dropForked.addColumn("forked", {dropColumn: true})
1108
+ for (const sql of await db.alterTableSQLs(dropForked)) await db.query(sql)
1109
+
1110
+ db.clearSchemaCache()
1111
+ }
1112
+
1113
+ await this._recordMigration(db, migrationVersion)
1114
+ } finally {
1115
+ await db.releaseAdvisoryLock(migrationKey)
1116
+ }
1117
+ }
1118
+
1023
1119
  /**
1024
1120
  * Runs record migration.
1025
1121
  * @param {import("../database/drivers/base.js").default} db - Database connection.
@@ -1097,7 +1193,6 @@ export default class BackgroundJobsStore {
1097
1193
  scheduledAt,
1098
1194
  shouldRetry
1099
1195
  })
1100
- if (shouldRetry && job.executionMode === "pooled") update.handoff_id = POOLED_QUEUED_HANDOFF_ID
1101
1196
 
1102
1197
  const affectedRows = await this._updateAffectedRows(db, {
1103
1198
  tableName: JOBS_TABLE,
@@ -1206,18 +1301,17 @@ export default class BackgroundJobsStore {
1206
1301
  * @returns {import("./types.js").BackgroundJobRow} - Normalized job row.
1207
1302
  */
1208
1303
  _normalizeJobRow(row) {
1209
- const persistedExecutionMode = row.execution_mode ? String(row.execution_mode) : null
1210
1304
  const handoffId = row.handoff_id ? String(row.handoff_id) : null
1211
- const executionMode = persistedExecutionMode
1212
- ? this._normalizePersistedExecutionMode({executionMode: persistedExecutionMode, handoffId})
1213
- : this._normalizeExecutionMode({forked: this._normalizeBoolean(row.forked)})
1305
+ // `execution_mode` is the single source of truth for a job's runtime and is
1306
+ // written on every enqueue; the drop-forked migration backfills any pre-existing
1307
+ // rows before the legacy `forked` column is removed.
1308
+ const executionMode = row.execution_mode ? this._normalizeExecutionModeName(String(row.execution_mode)) : DEFAULT_EXECUTION_MODE
1214
1309
 
1215
1310
  return {
1216
1311
  id: String(row.id),
1217
1312
  jobName: String(row.job_name),
1218
1313
  args: this._parseArgs(row.args_json),
1219
1314
  executionMode,
1220
- forked: executionMode !== "inline",
1221
1315
  queue: row.queue ? String(row.queue) : DEFAULT_QUEUE,
1222
1316
  status: row.status ? String(row.status) : "queued",
1223
1317
  attempts: this._normalizeNumber(row.attempts),
@@ -1501,19 +1595,6 @@ export default class BackgroundJobsStore {
1501
1595
  return numeric
1502
1596
  }
1503
1597
 
1504
- /**
1505
- * Runs normalize boolean.
1506
- * @param {?} value - Input value.
1507
- * @returns {boolean} - Normalized boolean.
1508
- */
1509
- _normalizeBoolean(value) {
1510
- if (value === null || value === undefined) return false
1511
- if (typeof value === "boolean") return value
1512
- if (typeof value === "number") return value !== 0
1513
-
1514
- return value === "true"
1515
- }
1516
-
1517
1598
  /**
1518
1599
  * Runs normalize execution mode.
1519
1600
  * @param {import("./types.js").BackgroundJobOptions} [options] - Job options.
@@ -1525,11 +1606,14 @@ export default class BackgroundJobsStore {
1525
1606
  if (executionMode) {
1526
1607
  return this._normalizeExecutionModeName(executionMode)
1527
1608
  }
1528
- // The legacy `forked` flag stays authoritative when supplied: `false` is
1529
- // inline and `true` is forked (never the pooled default). Only an enqueue
1530
- // that names neither option falls through to the pooled default.
1531
- if (options?.forked === false) return "inline"
1532
- if (options?.forked === true) return LEGACY_FORKED_EXECUTION_MODE
1609
+
1610
+ // The `forked` option alias was removed. Reject it loudly instead of silently
1611
+ // defaulting to pooled, which would turn an explicitly inline (`forked: false`)
1612
+ // or one-shot forked (`forked: true`) job into a pooled child-runner job — a
1613
+ // silent semantic change for any not-yet-migrated caller.
1614
+ if (options && "forked" in options) {
1615
+ throw new Error("The background job `forked` option was removed; pass `executionMode` (\"inline\", \"forked\", \"pooled\", or \"spawned\") instead")
1616
+ }
1533
1617
 
1534
1618
  return DEFAULT_EXECUTION_MODE
1535
1619
  }
@@ -1548,20 +1632,8 @@ export default class BackgroundJobsStore {
1548
1632
  }
1549
1633
 
1550
1634
  /**
1551
- * Normalizes a legacy-safe persisted execution mode.
1552
- * @param {object} args - Options.
1553
- * @param {string} args.executionMode - Persisted legacy execution mode.
1554
- * @param {string | null} args.handoffId - Persisted handoff id or pooled marker.
1555
- * @returns {import("./types.js").BackgroundJobExecutionMode} - Runtime execution mode.
1556
- */
1557
- _normalizePersistedExecutionMode({executionMode, handoffId}) {
1558
- if (executionMode === LEGACY_FORKED_EXECUTION_MODE && handoffId?.startsWith(POOLED_HANDOFF_ID_PREFIX)) return "pooled"
1559
-
1560
- return this._normalizeExecutionModeName(executionMode)
1561
- }
1562
-
1563
- /**
1564
- * Filters persisted legacy-safe execution modes.
1635
+ * Filters queued jobs by one or more execution modes against the
1636
+ * `execution_mode` column (the single source of truth).
1565
1637
  * @param {object} args - Options.
1566
1638
  * @param {import("../database/drivers/base.js").default} args.db - Database connection.
1567
1639
  * @param {import("./types.js").BackgroundJobExecutionMode | import("./types.js").BackgroundJobExecutionMode[]} args.executionMode - Runtime modes.
@@ -1570,20 +1642,8 @@ export default class BackgroundJobsStore {
1570
1642
  */
1571
1643
  _whereExecutionMode({db, executionMode, query}) {
1572
1644
  const executionModes = Array.isArray(executionMode) ? executionMode : [executionMode]
1573
- /** @type {string[]} */
1574
- const conditions = []
1575
1645
  const executionModeColumn = db.quoteColumn("execution_mode")
1576
- const handoffIdColumn = db.quoteColumn("handoff_id")
1577
-
1578
- for (const mode of executionModes) {
1579
- if (mode === "pooled") {
1580
- conditions.push(`(${executionModeColumn} = ${db.quote(LEGACY_FORKED_EXECUTION_MODE)} AND ${handoffIdColumn} = ${db.quote(POOLED_QUEUED_HANDOFF_ID)})`)
1581
- } else if (mode === LEGACY_FORKED_EXECUTION_MODE) {
1582
- conditions.push(`(${executionModeColumn} = ${db.quote(mode)} AND (${handoffIdColumn} IS NULL OR ${handoffIdColumn} <> ${db.quote(POOLED_QUEUED_HANDOFF_ID)}))`)
1583
- } else {
1584
- conditions.push(`${executionModeColumn} = ${db.quote(mode)}`)
1585
- }
1586
- }
1646
+ const conditions = executionModes.map((mode) => `${executionModeColumn} = ${db.quote(mode)}`)
1587
1647
 
1588
1648
  return query.where(`(${conditions.join(" OR ")})`)
1589
1649
  }
@@ -10,8 +10,7 @@
10
10
  */
11
11
  /**
12
12
  * @typedef {object} BackgroundJobOptions
13
- * @property {BackgroundJobExecutionMode} [executionMode] - How the job should run. Defaults to `"pooled"` (a warm, reused local runner process). `"forked"` runs the job in a fresh `child_process.fork()` child, `"spawned"` in a detached CLI runner, and `"inline"` inside the worker process.
14
- * @property {boolean} [forked] - Compatibility alias: `false` maps to `"inline"` and `true` maps to `"forked"`. Omitting both `forked` and `executionMode` uses the default `"pooled"` mode.
13
+ * @property {BackgroundJobExecutionMode} [executionMode] - How the job should run. Defaults to `"pooled"` (a warm, reused local runner process). `"forked"` runs the job in a fresh `child_process.fork()` child, `"spawned"` in a detached CLI runner, and `"inline"` inside the worker process. Omit to use the default `"pooled"` mode.
15
14
  * @property {number} [maxRetries] - Max retries for a failed job before it is marked failed.
16
15
  * @property {string} [queue] - Queue name. Defaults to `"default"`. When the queue has a configured cap in `backgroundJobs.queues`, that cap is enforced cluster-wide.
17
16
  * @property {string} [concurrencyKey] - Opaque non-empty key used to share a concurrency cap. Overrides any queue-derived cap.
@@ -35,7 +34,6 @@
35
34
  * @property {string} jobName - Job class name.
36
35
  * @property {Array<?>} args - Serialized job arguments.
37
36
  * @property {BackgroundJobExecutionMode} executionMode - How the job should run.
38
- * @property {boolean} forked - Compatibility flag; true for non-inline execution.
39
37
  * @property {string} queue - Queue name (defaults to `"default"`).
40
38
  * @property {string} status - Current job status.
41
39
  * @property {number | null} attempts - Failure attempts count.
@@ -196,7 +196,6 @@ export default class VelociousBackgroundJobsWebController extends Controller {
196
196
  createdAtMs: job.createdAtMs,
197
197
  executionMode: job.executionMode,
198
198
  failedAtMs: job.failedAtMs,
199
- forked: job.forked,
200
199
  handedOffAtMs: job.handedOffAtMs,
201
200
  id: job.id,
202
201
  jobName: job.jobName,
@@ -480,14 +480,9 @@ export default class BackgroundJobsWorker {
480
480
  * @returns {import("./types.js").BackgroundJobExecutionMode} - Execution mode.
481
481
  */
482
482
  _executionModeForPayload(payload) {
483
- const options = payload.options || {}
484
- const executionMode = options.executionMode
483
+ const executionMode = payload.options?.executionMode
485
484
 
486
- if (executionMode) return this._normalizeExecutionMode(executionMode)
487
-
488
- if (options.forked === false) return "inline"
489
- if (options.forked === true) return "forked"
490
- return "pooled"
485
+ return executionMode ? this._normalizeExecutionMode(executionMode) : "pooled"
491
486
  }
492
487
 
493
488
  /**
@@ -468,6 +468,26 @@ export default class VelociousDatabaseMigration {
468
468
  return Boolean(false)
469
469
  }
470
470
 
471
+ /**
472
+ * Checks whether an index with the given name exists on a table.
473
+ * @param {string} tableName - Table name.
474
+ * @param {string} indexName - Index name to look for.
475
+ * @returns {Promise<boolean>} - Whether the index exists on the table.
476
+ */
477
+ async indexExists(tableName, indexName) {
478
+ const table = await this.getDriver().getTableByName(tableName, {throwError: false})
479
+
480
+ if (table) {
481
+ for (const index of await table.getIndexes()) {
482
+ if (index.getName() == indexName) {
483
+ return true
484
+ }
485
+ }
486
+ }
487
+
488
+ return false
489
+ }
490
+
471
491
  /**
472
492
  * Sets up the database schema for a gap-less positional list. Adds the
473
493
  * position column (INT NOT NULL) if absent and creates a UNIQUE index on
@@ -204,6 +204,11 @@ export default class VelociousDatabaseMigrator {
204
204
 
205
205
  if (!environmentHandler || Object.keys(filteredDbs).length == 0) return
206
206
 
207
+ // Ensure velocious' own framework schema (background jobs) before the structure
208
+ // dump, and unconditionally — the dump is gated to enabled environments but the
209
+ // framework schema must exist after every migrate so `db:migrate` (and thus
210
+ // schema:load of the dumped SQL) produces a complete DB in every environment.
211
+ await environmentHandler.ensureFrameworkSchema({dbs: filteredDbs})
207
212
  await environmentHandler.afterMigrations({dbs: filteredDbs})
208
213
  }
209
214
 
@@ -508,6 +508,20 @@ export default class VelociousEnvironmentHandlerBase {
508
508
  return
509
509
  }
510
510
 
511
+ /**
512
+ * Ensures velocious' own framework-owned schema (e.g. the background-jobs
513
+ * tables) exists after app migrations run, so `db:migrate` produces a complete
514
+ * schema deterministically instead of it only appearing once a runtime store
515
+ * boots. Runs before the structure dump. No-op by default; the node handler
516
+ * overrides it.
517
+ * @param {object} args - Options object.
518
+ * @param {Record<string, import("../database/drivers/base.js").default>} args.dbs - Dbs being migrated.
519
+ * @returns {Promise<void>} - Resolves when complete.
520
+ */
521
+ async ensureFrameworkSchema(args) { // eslint-disable-line no-unused-vars
522
+ return
523
+ }
524
+
511
525
  /**
512
526
  * Runs require command.
513
527
  * @abstract
@@ -1005,6 +1005,29 @@ export default class VelociousEnvironmentHandlerNode extends Base{
1005
1005
  return basePath
1006
1006
  }
1007
1007
 
1008
+ /**
1009
+ * Ensures velocious' background-jobs schema exists on its configured database
1010
+ * as part of `db:migrate`, so the framework's own tables (background_jobs +
1011
+ * background_job_concurrency, execution_mode etc.) are created deterministically
1012
+ * alongside app migrations and captured in the dumped structure SQL — rather than
1013
+ * only appearing once a runtime store boots. Reuses the store's idempotent
1014
+ * `_ensureSchema`, so it's safe to re-run against DBs that already have it.
1015
+ * @param {object} args - Options object.
1016
+ * @param {Record<string, import("../database/drivers/base.js").default>} args.dbs - Dbs being migrated.
1017
+ * @returns {Promise<void>} - Resolves when complete.
1018
+ */
1019
+ async ensureFrameworkSchema({dbs}) {
1020
+ const {default: BackgroundJobsStore} = await import("../background-jobs/store.js")
1021
+ const store = new BackgroundJobsStore({configuration: this.getConfiguration()})
1022
+ const databaseIdentifier = store.getDatabaseIdentifier() ?? "default"
1023
+
1024
+ // Reuse the connection db:migrate already holds for this database; opening a
1025
+ // nested checkout would deadlock a database whose pool is capped at one
1026
+ // connection. When the background-jobs database isn't among the migrated set,
1027
+ // this passes undefined and the store checks out its own (that pool is free).
1028
+ await store.ensureSchema(dbs[databaseIdentifier])
1029
+ }
1030
+
1008
1031
  /**
1009
1032
  * Runs after migrations.
1010
1033
  * @param {object} args - Options object.
@@ -1 +1 @@
1
- {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../../src/background-jobs/main.js"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../../src/background-jobs/main.js"],"names":[],"mappings":"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"}