pg-boss 12.31.0 → 12.32.0

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/dist/manager.js CHANGED
@@ -3,6 +3,7 @@ import { randomUUID } from 'node:crypto';
3
3
  import EventEmitter from 'node:events';
4
4
  import { serializeError as stringify } from 'serialize-error';
5
5
  import * as Attorney from "./attorney.js";
6
+ import { TRANSACTION_ROLLBACK_TIMEOUT_MS } from "./db.js";
6
7
  import * as plans from "./plans.js";
7
8
  import * as timekeeper from "./timekeeper.js";
8
9
  import { resolveWithinSeconds } from "./tools.js";
@@ -10,6 +11,58 @@ import * as types from "./types.js";
10
11
  import Worker from "./worker.js";
11
12
  import { JobSpy } from "./spy.js";
12
13
  const INTERNAL_QUEUES = Object.values(timekeeper.QUEUES).reduce((acc, i) => ({ ...acc, [i]: i }), {});
14
+ // postgres: current transaction is aborted, commands ignored until end of transaction block
15
+ const TRANSACTION_ABORTED = '25P02';
16
+ // pg's own default when the pool size is not configured. Used to tell a transactional worker how
17
+ // much room it actually has, since each handler in flight holds a connection of its own.
18
+ const DEFAULT_POOL_MAX = 10;
19
+ const WARNING_TYPES = {
20
+ TRANSACTIONAL_POOL_HEADROOM: 'transactional_pool_headroom',
21
+ TRANSACTION_TIMEOUT_PROBE: 'transaction_timeout_probe'
22
+ };
23
+ const TRANSACTIONAL_HEARTBEAT_UNSUPPORTED = 'this backend cannot run a transactional worker on a queue with heartbeatSeconds: the heartbeat refreshes the claimed row from a pooled connection, which the handler transaction is then refused a write to. Drop heartbeatSeconds and let expireInSeconds bound the job, or drop transactional and settle it with complete({ db })';
24
+ // The same refusal from inside a batch, where the queue passed work()'s check and the heartbeat
25
+ // arrived afterwards: on the job itself (heartbeatSeconds on send()), or on the queue, through
26
+ // updateQueue() or through a createQueue() that work() ran ahead of. Pointing at the queue's
27
+ // configuration there would send the user to a setting that is not the one they need to drop.
28
+ const TRANSACTIONAL_HEARTBEAT_ON_BATCH = 'this backend cannot run a transactional handler over a job with heartbeatSeconds: the heartbeat refreshes the claimed row from a pooled connection, which the handler transaction is then refused a write to. The queue carried no heartbeat when this worker registered, so it came from the job (heartbeatSeconds on send()) or from the queue after registration. Drop it there and let expireInSeconds bound the job, or drop transactional and settle it with complete({ db })';
29
+ // Candidates for bounding a transactional handler's transaction from the database side, best
30
+ // first. transaction_timeout covers the whole transaction; idle_in_transaction_session_timeout only
31
+ // covers the gaps between statements, which still catches a handler that stops issuing them.
32
+ // statement_timeout is deliberately absent: it bounds one statement, and leaves the next one with
33
+ // 25P02, which would have the aborted-transaction message blame the handler for a SQL error it
34
+ // never swallowed.
35
+ const TRANSACTION_TIMEOUT_GUCS = ['transaction_timeout', 'idle_in_transaction_session_timeout'];
36
+ // current_setting(name, true) answers NULL for a parameter the server does not recognise, on every
37
+ // backend pg-boss supports, so which of the two is available takes one statement and no version
38
+ // parsing. transaction_timeout arrived in PostgreSQL 17 and exists on CockroachDB; asking for it on
39
+ // 13-16 any other way is a hard error.
40
+ const TRANSACTION_TIMEOUT_PROBE = `SELECT ${TRANSACTION_TIMEOUT_GUCS.map(name => `current_setting('${name}', true) AS ${name}`).join(', ')}`;
41
+ // The tighter of pg-boss's bound ($2, milliseconds) and the one the connection already carries for
42
+ // GUC $1. A role, a managed provider or a pooler that sets idle_in_transaction_session_timeout means
43
+ // it, and the transactions this runs on are the longest ones pg-boss opens, so overwriting it is
44
+ // exactly the wrong place to do so. pg_settings reports both GUCs unitless in milliseconds on every
45
+ // backend that has them, which current_setting does not, so the comparison needs no parsing and no
46
+ // second round trip. LEAST ignores nulls, which covers both cases where there is nothing to be
47
+ // tighter than: 0 is how either GUC spells "no bound" (NULLIF turns it into one of them), and a
48
+ // backend that recognises the parameter without listing it in pg_settings is the other. Read per
49
+ // transaction rather than cached, since the value belongs to the connection and not to the process.
50
+ const TRANSACTION_TIMEOUT_TIGHTEST = 'LEAST($2::bigint, NULLIF((SELECT s.setting::bigint FROM pg_settings s WHERE s.name = $1), 0))';
51
+ // Applies the bound. This is the first statement of the handler's transaction, so it must not be
52
+ // the first place a statement can fail: the read half is rehearsed by the probe below, on the
53
+ // pooled connection, and only set_config is new here. Sharing the expression is what keeps the two
54
+ // from drifting apart.
55
+ const TRANSACTION_TIMEOUT_APPLY = `SELECT set_config($1, ${TRANSACTION_TIMEOUT_TIGHTEST}::text, true)`;
56
+ // The read half of the apply, run once by the probe with a bound of 0 so it can set nothing. A
57
+ // backend or a db adapter that answers current_setting but has no pg_settings view fails here,
58
+ // where failing costs the bound, rather than inside the transaction, where it would cost the batch.
59
+ // set_config is left out on purpose: a custom adapter's executeSql may sit inside the caller's own
60
+ // open transaction, and a rehearsal must not be able to change anything there.
61
+ const TRANSACTION_TIMEOUT_REHEARSE = `SELECT ${TRANSACTION_TIMEOUT_TIGHTEST}`;
62
+ // How long a refused probe is remembered before the next transactional batch asks again. The bound
63
+ // is a backstop, so the retry has to stay; a backend that will never answer does not need to be
64
+ // asked on every batch for the life of the process either.
65
+ const TRANSACTION_TIMEOUT_PROBE_COOLDOWN_MS = 60_000;
13
66
  // CockroachDB returns integer columns (INT8) as strings; these aliased metadata
14
67
  // fields must be coerced back to numbers when backend === 'cockroachdb'.
15
68
  const NUMERIC_METADATA_FIELDS = [
@@ -58,6 +111,7 @@ const QUEUE_STATS_CACHE_TTL_SECONDS = 60 * 60;
58
111
  const QUEUE_STATS_FORCE_TTL_SECONDS = 60;
59
112
  const events = {
60
113
  error: 'error',
114
+ warning: 'warning',
61
115
  wip: 'wip'
62
116
  };
63
117
  // The fetch options that were performance escapes from the fetch's sort. The index is now ordered to
@@ -93,6 +147,20 @@ class Manager extends EventEmitter {
93
147
  queues;
94
148
  pendingOffWorkCleanups;
95
149
  #spies;
150
+ // Job ids a transactional handler settled itself through the transaction it was handed, keyed on
151
+ // that transaction's db. #processJobs reads it to interpret its own completion; see the check
152
+ // there. Weak because the key is the transaction, so an entry goes away with it.
153
+ #handlerSettledJobs;
154
+ // Which GUC this server bounds a transaction with, resolved on the first transactional batch and
155
+ // kept for the life of the process. Resolving to null means neither is recognised, or the probe
156
+ // itself failed; a failed probe clears the memo and sets the instant before which no batch asks
157
+ // again.
158
+ #transactionTimeoutGuc;
159
+ #transactionTimeoutProbeRetryAt;
160
+ #transactionTimeoutProbeCooldownMs;
161
+ // One warning per process for a probe the server will not answer. A backend or adapter that
162
+ // cannot answer it today will not answer it tomorrow, so there is no episode to report twice.
163
+ #warnedTransactionTimeoutProbe;
96
164
  #localGroupActive;
97
165
  #localGroupConfig;
98
166
  #localGroupMaxLimit;
@@ -105,6 +173,11 @@ class Manager extends EventEmitter {
105
173
  this.queues = {};
106
174
  this.pendingOffWorkCleanups = new Set();
107
175
  this.#spies = new Map();
176
+ this.#handlerSettledJobs = new WeakMap();
177
+ this.#transactionTimeoutGuc = null;
178
+ this.#transactionTimeoutProbeRetryAt = 0;
179
+ this.#transactionTimeoutProbeCooldownMs = config.__test__transactionTimeoutProbeCooldownMs ?? TRANSACTION_TIMEOUT_PROBE_COOLDOWN_MS;
180
+ this.#warnedTransactionTimeoutProbe = false;
108
181
  this.#localGroupActive = new Map();
109
182
  this.#localGroupConfig = new Map();
110
183
  this.#localGroupMaxLimit = new Map();
@@ -399,7 +472,18 @@ class Manager extends EventEmitter {
399
472
  }
400
473
  }
401
474
  }
402
- async #processJobs(name, jobs, callback, worker, heartbeatRefreshSeconds, perJobResults = false) {
475
+ /**
476
+ * Runs a batch through its handler and settles it.
477
+ *
478
+ * With `transactional`, the handler and the completion run in one transaction of their own. The
479
+ * batch is already claimed by the time this is called, so the transaction covers the handler's
480
+ * writes and the completion and nothing else: success commits them together, and a throw rolls
481
+ * both back and then fails the jobs on a pooled connection, where the retry accounting is the
482
+ * same as any other worker's. Because the claim is outside the transaction, the jobs stay
483
+ * visibly `active` throughout, which is what keeps heartbeats, `expireInSeconds`, and another
484
+ * instance's supervisor working on them as usual.
485
+ */
486
+ async #processJobs(name, jobs, callback, worker, heartbeatRefreshSeconds, perJobResults = false, transactional = false, transactionTimeoutSeconds) {
403
487
  const jobIds = jobs.map(job => job.id);
404
488
  const maxExpiration = jobs.reduce((acc, i) => Math.max(acc, i.expireInSeconds), 0);
405
489
  // Minimum, not maximum: heartbeatSeconds is per-job, and failJobsByHeartbeat fails a job once
@@ -413,6 +497,7 @@ class Manager extends EventEmitter {
413
497
  // Store AbortController on worker so it can be aborted after graceful shutdown
414
498
  if (worker) {
415
499
  worker.abortController = ac;
500
+ worker.aborted = false;
416
501
  }
417
502
  let heartbeatTimer = null;
418
503
  if (heartbeatSeconds > 0) {
@@ -431,8 +516,46 @@ class Manager extends EventEmitter {
431
516
  let completedAffected = 0;
432
517
  let failedError;
433
518
  let didFail = false;
519
+ // Only for a transactional worker, and only from the begin below until it settles. rollback()
520
+ // is idempotent, so the catch can settle it without tracking whether the commit got there
521
+ // first.
522
+ let transaction = null;
434
523
  try {
435
- const result = await resolveWithinSeconds(callback(jobs), maxExpiration, `handler execution exceeded ${maxExpiration}s`, ac);
524
+ // A per-job heartbeatSeconds, or updateQueue() after the worker registered, can put a
525
+ // heartbeat on a batch whose queue carried none at work(), which that check cannot see. Thrown
526
+ // before the begin so the batch takes the ordinary failure path rather than the backend's raw
527
+ // write conflict.
528
+ assert(!(transactional && heartbeatSeconds > 0 && this.config.noTransactionalHeartbeat), TRANSACTIONAL_HEARTBEAT_ON_BATCH);
529
+ if (transactional) {
530
+ const timeoutMs = transactionTimeoutSeconds !== undefined
531
+ ? transactionTimeoutSeconds * 1000
532
+ : maxExpiration * 1000 + TRANSACTION_ROLLBACK_TIMEOUT_MS;
533
+ // Asked before the begin. The probe runs on a pooled connection, and a pool whose
534
+ // connections the handlers in flight are already holding has none to hand it: the wait
535
+ // would then be connectionTimeoutMillis long, with this transaction open across it, and
536
+ // the bound lost for the whole cooldown after. Memoized after the first batch either way.
537
+ const timeoutGuc = timeoutMs > 0 ? await this.#resolveTransactionTimeoutGuc() : null;
538
+ transaction = await this.db.beginTransaction();
539
+ this.#handlerSettledJobs.set(transaction.db, new Set());
540
+ if (timeoutGuc) {
541
+ await this.#applyTransactionTimeout(transaction, timeoutGuc, timeoutMs);
542
+ }
543
+ }
544
+ const handling = transaction
545
+ ? callback(jobs, transaction.db)
546
+ : callback(jobs);
547
+ const result = await resolveWithinSeconds(handling, maxExpiration, `handler execution exceeded ${maxExpiration}s`, ac);
548
+ // An abort resolves the race rather than rejecting it, so on this line an abandoned handler
549
+ // looks exactly like one that returned. failWip() aborts after failing the batch, so
550
+ // committing here would leave whatever the handler had written by then in the database
551
+ // beside a job that is already failed: the split a transactional worker exists to prevent.
552
+ // Rolling back instead takes the same path a throw takes, and the fail that follows finds
553
+ // the jobs already settled and does nothing. The worker's flag rather than the signal,
554
+ // because resolveWithinSeconds cancels its own timeout through the same controller and so
555
+ // leaves the signal aborted on every ordinary completion too.
556
+ if (transaction && worker?.aborted) {
557
+ throw new Error('pg-boss shut down while the handler was still running');
558
+ }
436
559
  if (perJobResults) {
437
560
  // #settlePerJob settles each job individually and does its own (synchronous,
438
561
  // lookup-free) spy tracking via #trackJobsSettled, so the deferred tracker below
@@ -440,12 +563,33 @@ class Manager extends EventEmitter {
440
563
  await this.#settlePerJob(name, jobs, result);
441
564
  }
442
565
  else {
443
- const completion = await this.complete(name, jobIds, jobIds.length === 1 ? result : undefined);
566
+ // Read out before the completion below, which goes through the same complete() and would
567
+ // otherwise record pg-boss's own settle as one the handler made.
568
+ const settledByHandler = transaction ? this.#takeHandlerSettles(transaction) : null;
569
+ const completion = await this.complete(name, jobIds, jobIds.length === 1 ? result : undefined, transaction ? { db: transaction.db } : undefined);
444
570
  completedResult = result;
445
571
  completedAffected = completion.affected;
572
+ if (settledByHandler) {
573
+ this.#assertClaimHeld(jobIds, completion.affected, settledByHandler);
574
+ }
575
+ }
576
+ if (transaction) {
577
+ await transaction.commit();
446
578
  }
447
579
  }
448
580
  catch (err) {
581
+ if (transaction) {
582
+ // Before the fail, not after: fail() runs on a pooled connection and would otherwise wait
583
+ // on the job rows this transaction still holds locked.
584
+ await transaction.rollback();
585
+ // A handler that catches a SQL error it raised through the transaction leaves that
586
+ // transaction aborted, and postgres then rejects every later statement in it with 25P02,
587
+ // including the completion pg-boss runs there. Name the cause, since the raw message
588
+ // arrives with nothing to connect it to the handler.
589
+ if (err?.code === TRANSACTION_ABORTED) {
590
+ err.message = `${err.message} (the handler left its transaction aborted: let a SQL error raised through tx propagate out of the handler, or isolate the statement with a SAVEPOINT)`;
591
+ }
592
+ }
449
593
  await this.fail(name, jobIds, err);
450
594
  failedError = err;
451
595
  didFail = true;
@@ -474,6 +618,136 @@ class Manager extends EventEmitter {
474
618
  }
475
619
  }
476
620
  }
621
+ /**
622
+ * Gives the handler's transaction a deadline the database enforces.
623
+ *
624
+ * Everything else bounding it lives in this process: `resolveWithinSeconds` and the deadline
625
+ * `rollback()` races its ROLLBACK against. Those cover a handler that hangs. They do not cover
626
+ * the process itself failing under it (a starved event loop, a driver wedged below the promise),
627
+ * which is the case that matters most. An open transaction keeps advertising `backend_xmin` and
628
+ * holds vacuum off the whole database for as long as it lasts, which is the condition
629
+ * `monitorVacuum` and the `xmin_horizon` warning exist to report, and this option is what makes a
630
+ * long-lived transaction reachable from user code in the first place.
631
+ *
632
+ * The default is derived from `expireInSeconds` rather than matched to it. Matching would make
633
+ * the diagnosis a coin flip between `handler execution exceeded Ns` with a clean rollback and a
634
+ * killed connection, and the transaction is open wider than the handler anyway (BEGIN precedes
635
+ * it, the completion and COMMIT follow it), so an equal bound would kill a batch that had already
636
+ * succeeded at its commit. `expireInSeconds` is also the supervisor's reclaim bound, and a third
637
+ * actor on that instant helps nobody. With the rollback deadline added on top, this only fires
638
+ * once the whole Node path has failed, which is when the server should be the one to give up.
639
+ *
640
+ * Issued here on `tx.db` rather than as a `beginTransaction()` argument: that method is public
641
+ * `IDatabase` surface, so an adapter that ignored a new parameter would drop the bound silently.
642
+ * `set_config` with the value bound rather than a built `SET LOCAL` string, so it is one
643
+ * parameterized statement and portable to drivers that reject multi-statement queries.
644
+ */
645
+ async #applyTransactionTimeout(transaction, guc, timeoutMs) {
646
+ await transaction.db.executeSql(TRANSACTION_TIMEOUT_APPLY, [guc, `${Math.round(timeoutMs)}`]);
647
+ }
648
+ /**
649
+ * Which GUC this server bounds a transaction with, or null if neither is available and the
650
+ * transaction runs unbounded.
651
+ *
652
+ * Asked on the pooled connection rather than the handler's, even though the bound is applied on
653
+ * the handler's. A statement that errors leaves its transaction aborted, so a probe the backend
654
+ * or a `db` adapter cannot answer would poison the very transaction it was meant to protect and
655
+ * every handler statement after it would come back 25P02 blaming the handler for a SQL error it
656
+ * never raised. Off the transaction, a failed probe costs the bound and nothing else.
657
+ *
658
+ * Asked before the begin for the same reason it is asked off the transaction: a pool whose
659
+ * connections the handlers in flight are holding has none left for the probe, so a probe issued
660
+ * after the begin waits out `connectionTimeoutMillis` with that transaction open and then loses
661
+ * the bound for the whole cooldown. Only the first batch of a process pays anything here.
662
+ *
663
+ * The apply statement also reads pg_settings, and it runs as the first statement of the handler's
664
+ * transaction, so the probe rehearses that read here as well. Otherwise a backend with the GUC but
665
+ * without the catalog view would fail every batch, silently as far as the warning system goes,
666
+ * which is the failure the probe exists to keep out of the transaction.
667
+ *
668
+ * The bound is a backstop against a process that has already failed, so losing it degrades rather
669
+ * than fails the batch: warn once, run this batch unbounded, and ask again once the cooldown has
670
+ * passed instead of running unbounded for the life of the process, or asking on every batch.
671
+ */
672
+ #resolveTransactionTimeoutGuc() {
673
+ if (!this.#transactionTimeoutGuc && Date.now() < this.#transactionTimeoutProbeRetryAt) {
674
+ return Promise.resolve(null);
675
+ }
676
+ this.#transactionTimeoutGuc ??= this.db.executeSql(TRANSACTION_TIMEOUT_PROBE)
677
+ .then(({ rows }) => TRANSACTION_TIMEOUT_GUCS.find(name => rows[0][name] !== null) ?? null)
678
+ .then(async (guc) => {
679
+ if (guc)
680
+ await this.db.executeSql(TRANSACTION_TIMEOUT_REHEARSE, [guc, '0']);
681
+ return guc;
682
+ })
683
+ .catch((err) => {
684
+ this.#transactionTimeoutGuc = null;
685
+ this.#transactionTimeoutProbeRetryAt = Date.now() + this.#transactionTimeoutProbeCooldownMs;
686
+ if (!this.#warnedTransactionTimeoutProbe) {
687
+ this.#warnedTransactionTimeoutProbe = true;
688
+ this.emit(events.warning, {
689
+ message: `could not ask this server which transaction timeout it supports, or read the bound it already carries, so transactional handlers run with no database-side bound until the next probe: ${err.message}`,
690
+ data: { type: WARNING_TYPES.TRANSACTION_TIMEOUT_PROBE }
691
+ });
692
+ }
693
+ return null;
694
+ });
695
+ return this.#transactionTimeoutGuc;
696
+ }
697
+ /**
698
+ * Guards the commit of a transactional batch on the worker still holding the claim it opened the
699
+ * transaction with.
700
+ *
701
+ * `complete()` only settles a job that is still `active`, so a short count means the rows were
702
+ * taken out of that state while the handler ran. Two things do that. The handler may have settled
703
+ * the jobs itself with `complete()`, `fail()`, `cancel()` or `deleteJob()` on `{ db: tx }`, which
704
+ * is a documented pattern and leaves pg-boss's own completion with nothing to update; those calls
705
+ * record their ids as they land, so they cost no round trip to recognise. Anything left over is a
706
+ * claim that went away: an operator's `cancel()` or `fail()`, a heartbeat the database stopped
707
+ * seeing, `expireInSeconds`, another instance's supervisor. That job is going to run again, so
708
+ * committing the handler's writes beside it produces exactly the duplicate side effect this
709
+ * option exists to prevent. Throwing rolls them back and takes the ordinary failure path, which
710
+ * records the failure against whatever state the job is in by then.
711
+ *
712
+ * A handler that settles its own jobs by writing the job table directly also lands here, since
713
+ * nothing about a raw `UPDATE` is recognisable as a settle. That is a narrowing rather than a
714
+ * regression: direct writes to the job table were never supported. The message has to offer that
715
+ * reading anyway, so the diagnosis is not sent after a claim that was never lost.
716
+ */
717
+ #assertClaimHeld(jobIds, affected, settledByHandler) {
718
+ const accounted = affected + jobIds.filter(id => settledByHandler.has(id)).length;
719
+ if (accounted < jobIds.length) {
720
+ throw new Error(`${jobIds.length - accounted} of ${jobIds.length} job(s) were no longer claimed by this worker when the handler returned, so the transaction was rolled back. Either something took the claim away (expireInSeconds, a heartbeat the database stopped seeing, an operator's cancel() or fail(), another instance's supervisor), or the handler settled the job with SQL of its own instead of complete(), fail(), cancel() or deleteJob() on { db: tx }`);
721
+ }
722
+ }
723
+ // The ids the handler settled through its transaction. Taken rather than read, so the completion
724
+ // pg-boss runs next on the same transaction does not add itself to the set.
725
+ #takeHandlerSettles(transaction) {
726
+ const settled = this.#handlerSettledJobs.get(transaction.db) ?? new Set();
727
+ this.#handlerSettledJobs.delete(transaction.db);
728
+ return settled;
729
+ }
730
+ // Records a settle a transactional handler ran through the transaction it was handed. A no-op for
731
+ // every other caller: only a transaction #processJobs opened is in the map.
732
+ //
733
+ // Records the ids the statement touched rather than the ids it was asked about, because the two
734
+ // differ in both directions. complete() on a job a peer already moved out of `active` updates no
735
+ // rows, and recording that as the handler's settle would account for a job nobody settled and let
736
+ // the batch commit, which is the duplicate #assertClaimHeld exists to stop. A handler that
737
+ // settles part of its own batch first then asks about all of it lands short for the opposite
738
+ // reason, and reading that as a lost claim would throw away a batch that did what it was asked.
739
+ // The count alone cannot tell those apart; the ids can, and the statement already returns them.
740
+ #trackHandlerSettle(options, response) {
741
+ const settled = options.db && this.#handlerSettledJobs.get(options.db);
742
+ if (!settled)
743
+ return;
744
+ // Without the ids there is no way to attribute a short count, so fall back to the all-or-nothing
745
+ // reading: a full settle is the handler's, anything less is left for #assertClaimHeld to judge.
746
+ const landed = response.settled ?? (response.affected < response.requested ? [] : response.jobs);
747
+ for (const id of landed) {
748
+ settled.add(id);
749
+ }
750
+ }
477
751
  async start() {
478
752
  this.stopped = false;
479
753
  this.queueCacheInterval = setInterval(() => this.onCacheQueues({ emit: true }), this.config.queueCacheIntervalSeconds * 1000);
@@ -529,11 +803,31 @@ class Manager extends EventEmitter {
529
803
  this.#localGroupActive.clear();
530
804
  this.#localGroupMaxLimit.clear();
531
805
  }
806
+ // Last step of a shutdown: closing the pool, marking the instance stopped, and emitting
807
+ // `stopped` all wait on this, so every worker has to be reached even when one of them cannot be
808
+ // failed.
532
809
  async failWip() {
533
810
  for (const worker of this.workers.values()) {
534
811
  const jobIds = worker.jobs.map(j => j.id);
535
812
  if (jobIds.length) {
536
- await this.fail(worker.name, jobIds, 'pg-boss shut down while active');
813
+ // The fail goes in before the abort, so it lands while the handler is still holding the
814
+ // jobs active and its completion finds nothing to settle. Its own failure is reported
815
+ // rather than thrown: the remaining workers still have to be aborted.
816
+ try {
817
+ await this.fail(worker.name, jobIds, 'pg-boss shut down while active');
818
+ }
819
+ catch (err) {
820
+ try {
821
+ this.emit(events.error, { ...err, message: err.message, stack: err.stack, queue: worker.name, worker: worker.id });
822
+ }
823
+ catch {
824
+ // An `error` event nobody listens for throws ERR_UNHANDLED_ERROR straight back out of
825
+ // emit(). Counting listeners here would not see it: the PgBoss instance re-emits this
826
+ // event, so the throw comes from an application with no `error` handler, one frame
827
+ // further out than this emitter can measure. Reporting the failure matters less than
828
+ // reaching the workers after this one, the pool close, and the `stopped` event.
829
+ }
830
+ }
537
831
  }
538
832
  worker.abort();
539
833
  }
@@ -543,7 +837,15 @@ class Manager extends EventEmitter {
543
837
  if (this.stopped) {
544
838
  throw new Error('Workers are disabled. pg-boss is stopped');
545
839
  }
546
- const { pollingInterval: interval, notifyPollingInterval: notifyInterval, burstWhenReadyExceeds, burstWhenBatchFull = false, batchSize = 1, includeMetadata = false, priority = true, localConcurrency = 1, localGroupConcurrency, groupConcurrency, orderByCreatedOn = true, heartbeatRefreshSeconds, minPriority, maxPriority, perJobResults = false, } = options;
840
+ const { pollingInterval: interval, notifyPollingInterval: notifyInterval, burstWhenReadyExceeds, burstWhenBatchFull = false, batchSize = 1, includeMetadata = false, priority = true, localConcurrency = 1, localGroupConcurrency, groupConcurrency, orderByCreatedOn = true, heartbeatRefreshSeconds, minPriority, maxPriority, perJobResults = false, transactional = false, transactionTimeoutSeconds, } = options;
841
+ // Capability check rather than a check for the built-in pool, so a db adapter that implements
842
+ // beginTransaction can serve transactional workers too. Asserted at work() time so the mistake
843
+ // surfaces on the call rather than on the first fetch.
844
+ if (transactional) {
845
+ assert(typeof this.db.beginTransaction === 'function', 'transactional workers require a database connection pg-boss can open a transaction on: the built-in pool, or a db adapter implementing beginTransaction');
846
+ await this.#assertTransactionalHeartbeatSupported(name);
847
+ this.#warnOnTransactionalPoolHeadroom(localConcurrency);
848
+ }
547
849
  if (localGroupConcurrency != null) {
548
850
  this.#storeLocalGroupConfig(name, localGroupConcurrency);
549
851
  }
@@ -588,7 +890,7 @@ class Manager extends EventEmitter {
588
890
  const worker = this.workers.get(workerId);
589
891
  // Skip all in-memory group tracking when localGroupConcurrency is not enabled
590
892
  if (localGroupConcurrency == null) {
591
- await this.#processJobs(name, jobs, callback, worker, heartbeatRefreshSeconds, perJobResults);
893
+ await this.#processJobs(name, jobs, callback, worker, heartbeatRefreshSeconds, perJobResults, transactional, transactionTimeoutSeconds);
592
894
  }
593
895
  else {
594
896
  const { allowed, excess, groupedJobs } = this.#trackLocalGroupStart(name, jobs);
@@ -598,7 +900,7 @@ class Manager extends EventEmitter {
598
900
  await this.restore(name, excessIds);
599
901
  }
600
902
  if (allowed.length > 0) {
601
- await this.#processJobs(name, allowed, callback, worker, heartbeatRefreshSeconds, perJobResults);
903
+ await this.#processJobs(name, allowed, callback, worker, heartbeatRefreshSeconds, perJobResults, transactional, transactionTimeoutSeconds);
602
904
  }
603
905
  }
604
906
  finally {
@@ -621,6 +923,58 @@ class Manager extends EventEmitter {
621
923
  }
622
924
  return firstWorkerId;
623
925
  }
926
+ /**
927
+ * Refuses a transactional worker on a queue that configures heartbeats, where the backend cannot
928
+ * carry both.
929
+ *
930
+ * `touch()` refreshes `heartbeat_on` on the claimed row from a pooled connection so the job stays
931
+ * visibly `active` while the handler runs. Under CockroachDB's serializable isolation that write
932
+ * lands above the handler transaction's timestamp and the completion pg-boss runs inside the
933
+ * transaction then cannot write the same row: `40001` WriteTooOldError, every batch. The
934
+ * transaction has already returned rows to the handler, so there is no read timestamp left to
935
+ * refresh and no retry to make in place.
936
+ *
937
+ * Neither half survives being dropped quietly. Skipping the refresh would leave `heartbeat_on`
938
+ * to go stale under a live handler, and `failJobsByHeartbeat` would reclaim exactly the
939
+ * long-running jobs heartbeats exist for, so the batch would roll back and retry forever with
940
+ * nothing in the output to say why. Rejecting at registration says it once, where the
941
+ * configuration is.
942
+ *
943
+ * Only queried on a backend that sets the flag, so `work()` stays off the database everywhere
944
+ * else. A per-job `heartbeatSeconds` can still override a queue that has none, which this call
945
+ * cannot see; #processJobs catches that from the batch itself.
946
+ */
947
+ async #assertTransactionalHeartbeatSupported(name) {
948
+ if (!this.config.noTransactionalHeartbeat)
949
+ return;
950
+ // A queue that does not exist yet cannot be read, and work() has never required one. The batch
951
+ // check is the backstop either way.
952
+ const queue = await this.getQueue(name).catch(() => null);
953
+ assert(!queue?.heartbeatSeconds, TRANSACTIONAL_HEARTBEAT_UNSUPPORTED);
954
+ }
955
+ // Each transactional handler in flight holds a pool connection for its own duration, so a pool
956
+ // sized at or below the number of them has nothing left for the fetches, the failures, or
957
+ // maintenance: those wait out connectionTimeoutMillis and then reject. Only measurable for the
958
+ // built-in pool, and a warning rather than an assert, because the ceiling is the operator's call.
959
+ //
960
+ // Emitted only, never persisted. The `warning` table records episodes, and every type in it is
961
+ // deduped by a flag that clears when the condition does. This one is an assertion about static
962
+ // configuration with no episode behind it: `max` is fixed for the life of the process, so every
963
+ // later transactional work() call trips it again with a larger `pinned`, and every restart writes
964
+ // the same rows once more. Persisting it would bury the warnings someone actually needs.
965
+ #warnOnTransactionalPoolHeadroom(localConcurrency) {
966
+ if (!this.db._pgbdb)
967
+ return;
968
+ const max = this.config.max ?? DEFAULT_POOL_MAX;
969
+ const running = [...this.workers.values()].filter(worker => worker.options.transactional).length;
970
+ const pinned = running + localConcurrency;
971
+ if (pinned < max)
972
+ return;
973
+ this.emit(events.warning, {
974
+ message: `transactional workers can hold ${pinned} of this pool's ${max} connections while their handlers run, leaving nothing for fetches, failures, or maintenance. Raise max above ${pinned}, or lower localConcurrency.`,
975
+ data: { type: WARNING_TYPES.TRANSACTIONAL_POOL_HEADROOM, max, transactionalWorkers: pinned }
976
+ });
977
+ }
624
978
  addWorker(worker) {
625
979
  this.workers.set(worker.id, worker);
626
980
  }
@@ -1175,7 +1529,11 @@ class Manager extends EventEmitter {
1175
1529
  return {
1176
1530
  jobs: ids,
1177
1531
  requested: ids.length,
1178
- affected: result && result.rows ? parseInt(result.rows[0].count) : 0
1532
+ affected: result && result.rows ? parseInt(result.rows[0].count) : 0,
1533
+ // The settle statements aggregate the ids they touched beside the count; the read-only
1534
+ // mutators that share this mapper (resume, restore, retry, touch) do not, so it stays
1535
+ // optional and #trackHandlerSettle falls back to the count when it is absent.
1536
+ settled: result?.rows?.[0]?.ids
1179
1537
  };
1180
1538
  }
1181
1539
  async complete(name, id, data, options = {}) {
@@ -1184,14 +1542,19 @@ class Manager extends EventEmitter {
1184
1542
  const ids = this.mapCompletionIdArg(id, 'complete');
1185
1543
  const { table } = await this.getQueueCache(name);
1186
1544
  const outputData = this.mapCompletionDataArg(data);
1545
+ let response;
1187
1546
  // noMultiMutationCte: split the dependency-unblocking into a separate statement to
1188
1547
  // avoid CockroachDB's multi-mutation CTE limitation (completeJobs updates two tables).
1189
1548
  if (this.config.noMultiMutationCte) {
1190
- return this.completeDistributed(name, ids, outputData, table, db, options.includeQueued);
1549
+ response = await this.completeDistributed(name, ids, outputData, table, db, options.includeQueued);
1191
1550
  }
1192
- const sql = plans.completeJobs(this.config.schema, table, options.includeQueued);
1193
- const result = await db.executeSql(sql, [name, ids, outputData]);
1194
- return this.mapCommandResponse(ids, result);
1551
+ else {
1552
+ const sql = plans.completeJobs(this.config.schema, table, options.includeQueued);
1553
+ const result = await db.executeSql(sql, [name, ids, outputData]);
1554
+ response = this.mapCommandResponse(ids, result);
1555
+ }
1556
+ this.#trackHandlerSettle(options, response);
1557
+ return response;
1195
1558
  }
1196
1559
  // Distributed complete/fail need several statements run atomically. When we own the pooled
1197
1560
  // connection we pin a single client via withTransaction(); when the caller supplied their own
@@ -1208,7 +1571,7 @@ class Manager extends EventEmitter {
1208
1571
  // completion is a single statement on every backend.
1209
1572
  const sql = plans.completeJobsDistributed(this.config.schema, table, includeQueued);
1210
1573
  const { rows } = await db.executeSql(sql, [name, ids, outputData]);
1211
- return { jobs: ids, requested: ids.length, affected: rows.length };
1574
+ return { jobs: ids, requested: ids.length, affected: rows.length, settled: rows.map(row => row.id) };
1212
1575
  }
1213
1576
  async fail(name, id, data, options = {}) {
1214
1577
  Attorney.assertQueueName(name);
@@ -1216,15 +1579,20 @@ class Manager extends EventEmitter {
1216
1579
  const ids = this.mapCompletionIdArg(id, 'fail');
1217
1580
  const { table } = await this.getQueueCache(name);
1218
1581
  const outputData = this.mapCompletionDataArg(data);
1582
+ let response;
1219
1583
  // noMultiMutationCte: use separate queries to avoid CockroachDB's multi-mutation CTE limitation.
1220
1584
  // The delete and re-insert run in a single transaction (see ensureTransaction) so the
1221
1585
  // job cannot be lost between the two statements.
1222
1586
  if (this.config.noMultiMutationCte) {
1223
- return this.failDistributed(name, ids, outputData, table, db);
1587
+ response = await this.failDistributed(name, ids, outputData, table, db);
1224
1588
  }
1225
- const sql = plans.failJobsById(this.config.schema, table);
1226
- const result = await db.executeSql(sql, [name, ids, outputData]);
1227
- return this.mapCommandResponse(ids, result);
1589
+ else {
1590
+ const sql = plans.failJobsById(this.config.schema, table);
1591
+ const result = await db.executeSql(sql, [name, ids, outputData]);
1592
+ response = this.mapCommandResponse(ids, result);
1593
+ }
1594
+ this.#trackHandlerSettle(options, response);
1595
+ return response;
1228
1596
  }
1229
1597
  async failDistributed(name, ids, outputData, table, db) {
1230
1598
  // CockroachDB doesn't support multi-mutation CTEs, but does support transactions, so the
@@ -1234,14 +1602,14 @@ class Manager extends EventEmitter {
1234
1602
  const selectQuery = plans.selectJobsToFailById(this.config.schema, table);
1235
1603
  const { rows: jobs } = await tx.executeSql(selectQuery.text, [name, ids]);
1236
1604
  if (jobs.length === 0) {
1237
- return { jobs: ids, requested: ids.length, affected: 0 };
1605
+ return { jobs: ids, requested: ids.length, affected: 0, settled: [] };
1238
1606
  }
1239
1607
  // Step 2: Delete the jobs
1240
1608
  const deleteQuery = plans.deleteJobsToFail(this.config.schema, table);
1241
1609
  await tx.executeSql(deleteQuery.text, [name, ids]);
1242
1610
  // Step 3: Re-insert jobs with updated state
1243
1611
  const count = await this.reinsertFailedJobs(tx, table, jobs, outputData);
1244
- return { jobs: ids, requested: ids.length, affected: count };
1612
+ return { jobs: ids, requested: ids.length, affected: count, settled: jobs.map(job => job.id) };
1245
1613
  });
1246
1614
  }
1247
1615
  // Distributed equivalents of the supervisor's failJobsByTimeout/failJobsByHeartbeat maintenance.
@@ -1371,7 +1739,9 @@ class Manager extends EventEmitter {
1371
1739
  const { table } = await this.getQueueCache(name);
1372
1740
  const sql = plans.deleteJobsById(this.config.schema, table);
1373
1741
  const result = await db.executeSql(sql, [name, ids]);
1374
- return this.mapCommandResponse(ids, result);
1742
+ const response = this.mapCommandResponse(ids, result);
1743
+ this.#trackHandlerSettle(options, response);
1744
+ return response;
1375
1745
  }
1376
1746
  async redrive(name, options = {}) {
1377
1747
  Attorney.assertQueueName(name);
@@ -1396,7 +1766,9 @@ class Manager extends EventEmitter {
1396
1766
  const { table } = await this.getQueueCache(name);
1397
1767
  const sql = plans.cancelJobs(this.config.schema, table);
1398
1768
  const result = await db.executeSql(sql, [name, ids]);
1399
- return this.mapCommandResponse(ids, result);
1769
+ const response = this.mapCommandResponse(ids, result);
1770
+ this.#trackHandlerSettle(options, response);
1771
+ return response;
1400
1772
  }
1401
1773
  async resume(name, id, options = {}) {
1402
1774
  Attorney.assertQueueName(name);
@@ -1 +1 @@
1
- {"version":3,"file":"plans.d.ts","sourceRoot":"","sources":["../src/plans.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"plans.d.ts","sourceRoot":"","sources":["../src/plans.ts"],"names":[],"mappings":"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"}