pg-boss 12.28.0 → 12.29.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/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  Queueing jobs in Postgres from Node.js like a boss.
2
2
 
3
3
  [![Build](https://github.com/timgit/pg-boss/actions/workflows/ci.yml/badge.svg?branch=master)](https://github.com/timgit/pg-boss/actions/workflows/ci.yml)
4
- [![Coverage](https://img.shields.io/coverallsCoverage/github/timgit/pg-boss)](https://coveralls.io/github/timgit/pg-boss?branch=master)
4
+ [![Coverage](https://coveralls.io/repos/github/timgit/pg-boss/badge.svg?branch=master)](https://coveralls.io/github/timgit/pg-boss?branch=master)
5
5
  [![NPM](https://img.shields.io/npm/v/pg-boss)](https://www.npmjs.com/package/pg-boss)
6
6
 
7
7
 
@@ -85,10 +85,10 @@ pg-boss is MIT licensed and always will be. It is maintained by one person, and
85
85
 
86
86
  <!-- sponsors:start The logos below are generated from GitHub Sponsors by scripts/sync-sponsors.js. Do not edit them directly. -->
87
87
  <div style="display: flex; flex-wrap: wrap; gap: 1rem; align-items: center; margin: 1.5rem 0;">
88
+ <a href="https://superpower.com/" target="_blank" rel="noopener"><img src="https://avatars.githubusercontent.com/u/114334709?s=200&amp;v=4" alt="Superpower" title="Superpower" width="96" height="96" style="border-radius: 8px;"></a>
88
89
  <a href="https://altruistiq.com/" target="_blank" rel="noopener"><img src="https://avatars.githubusercontent.com/u/88195975?s=200&amp;v=4" alt="Altruistiq" title="Altruistiq" width="64" height="64" style="border-radius: 8px;"></a>
89
90
  <a href="https://wasp.sh/" target="_blank" rel="noopener"><img src="https://avatars.githubusercontent.com/u/55102317?s=200&amp;v=4" alt="wasp-lang" title="wasp-lang" width="64" height="64" style="border-radius: 8px;"></a>
90
91
  <a href="https://github.com/Ferry-Health" target="_blank" rel="noopener"><img src="https://avatars.githubusercontent.com/u/158637456?s=200&amp;v=4" alt="Ferry Health" title="Ferry Health" width="64" height="64" style="border-radius: 8px;"></a>
91
- <a href="https://superpower.com/" target="_blank" rel="noopener"><img src="https://avatars.githubusercontent.com/u/114334709?s=200&amp;v=4" alt="Superpower" title="Superpower" width="64" height="64" style="border-radius: 8px;"></a>
92
92
  </div>
93
93
  <!-- sponsors:end -->
94
94
 
@@ -1 +1 @@
1
- {"version":3,"file":"attorney.d.ts","sourceRoot":"","sources":["../src/attorney.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,KAAK,MAAM,YAAY,CAAA;AAExC,QAAA,MAAM,MAAM;;;;CAIX,CAAA;AAqED,iBAAS,iBAAiB,CAAE,MAAM,GAAE,GAAQ,QAc3C;AAgBD,iBAAS,mBAAmB,CAAE,KAAK,EAAE,MAAM,UAE1C;AAED,iBAAS,aAAa,CAAE,IAAI,EAAE,GAAG,GAAG,KAAK,CAAC,OAAO,CAgDhD;AAOD,iBAAS,eAAe,CAAE,IAAI,EAAE,GAAG,EAAE,EAAE,MAAc,EAAE;;CAAK,GAAG,KAAK,CAAC,OAAO,CA4D3E;AAED,iBAAS,mBAAmB,CAAE,MAAM,EAAE,GAAG,QAOxC;AAED,iBAAS,gBAAgB,CAAE,IAAI,EAAE,KAAK,CAAC,OAAO,EAAE,QA2D/C;AA2GD,iBAAS,aAAa,CAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG;IAClD,OAAO,EAAE,KAAK,CAAC,mBAAmB,CAAA;IAClC,QAAQ,EAAE,KAAK,CAAC,WAAW,CAAC,GAAG,CAAC,CAAA;CACjC,CA8BA;AAED,iBAAS,cAAc,CAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,QAQlD;AAED,iBAAS,SAAS,CAAE,KAAK,EAAE,MAAM,GAAG,KAAK,CAAC,kBAAkB,GAAG,KAAK,CAAC,0BAA0B,CAwB9F;AAsFD,iBAAS,wBAAwB,CAAE,IAAI,EAAE,MAAM,QAiC9C;AAED,iBAAS,eAAe,CAAE,IAAI,EAAE,MAAM,QAIrC;AAED,iBAAS,SAAS,CAAE,GAAG,EAAE,MAAM,QAI9B;AAuJD,OAAO,EACL,SAAS,EACT,wBAAwB,EACxB,eAAe,EACf,cAAc,EACd,aAAa,EACb,eAAe,EACf,aAAa,EACb,SAAS,EACT,mBAAmB,EACnB,MAAM,EACN,gBAAgB,EAChB,mBAAmB,EACnB,iBAAiB,EAClB,CAAA"}
1
+ {"version":3,"file":"attorney.d.ts","sourceRoot":"","sources":["../src/attorney.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,KAAK,MAAM,YAAY,CAAA;AAExC,QAAA,MAAM,MAAM;;;;CAIX,CAAA;AA+ED,iBAAS,iBAAiB,CAAE,MAAM,GAAE,GAAQ,QAc3C;AAgBD,iBAAS,mBAAmB,CAAE,KAAK,EAAE,MAAM,UAE1C;AAED,iBAAS,aAAa,CAAE,IAAI,EAAE,GAAG,GAAG,KAAK,CAAC,OAAO,CAgDhD;AAOD,iBAAS,eAAe,CAAE,IAAI,EAAE,GAAG,EAAE,EAAE,MAAc,EAAE;;CAAK,GAAG,KAAK,CAAC,OAAO,CA4D3E;AAED,iBAAS,mBAAmB,CAAE,MAAM,EAAE,GAAG,QAOxC;AAED,iBAAS,gBAAgB,CAAE,IAAI,EAAE,KAAK,CAAC,OAAO,EAAE,QA2D/C;AA2GD,iBAAS,aAAa,CAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG;IAClD,OAAO,EAAE,KAAK,CAAC,mBAAmB,CAAA;IAClC,QAAQ,EAAE,KAAK,CAAC,WAAW,CAAC,GAAG,CAAC,CAAA;CACjC,CA8BA;AAED,iBAAS,cAAc,CAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,QAQlD;AAED,iBAAS,SAAS,CAAE,KAAK,EAAE,MAAM,GAAG,KAAK,CAAC,kBAAkB,GAAG,KAAK,CAAC,0BAA0B,CAyB9F;AA4FD,iBAAS,wBAAwB,CAAE,IAAI,EAAE,MAAM,QAiC9C;AAED,iBAAS,eAAe,CAAE,IAAI,EAAE,MAAM,QAIrC;AAED,iBAAS,SAAS,CAAE,GAAG,EAAE,MAAM,QAI9B;AAuLD,OAAO,EACL,SAAS,EACT,wBAAwB,EACxB,eAAe,EACf,cAAc,EACd,aAAa,EACb,eAAe,EACf,aAAa,EACb,SAAS,EACT,mBAAmB,EACnB,MAAM,EACN,gBAAgB,EAChB,mBAAmB,EACnB,iBAAiB,EAClB,CAAA"}
package/dist/attorney.js CHANGED
@@ -16,7 +16,8 @@ const COMPATIBILITY_FLAGS = [
16
16
  'noAdvisoryLocks',
17
17
  'noCoveringIndexes',
18
18
  'noListenNotify',
19
- 'noIndexProgressView'
19
+ 'noIndexProgressView',
20
+ 'noReindex'
20
21
  ];
21
22
  // The single source of truth for backend presets, mirrored by test/testHelper.ts.
22
23
  const BACKEND_PROFILES = {
@@ -33,7 +34,12 @@ const BACKEND_PROFILES = {
33
34
  noListenNotify: true,
34
35
  // Online DDL runs as a schema-change job, not the PG CONCURRENTLY path, and
35
36
  // pg_stat_progress_create_index isn't available — so BAM can't use liveness-based reclaim.
36
- noIndexProgressView: true
37
+ noIndexProgressView: true,
38
+ // REINDEX is rejected in either form — "CockroachDB does not require reindexing" with
39
+ // CONCURRENTLY, "unimplemented: this syntax" without — and the bloat check itself cannot run:
40
+ // there is no pg_relation_size(), and reltuples / relpages is an "unsupported binary
41
+ // operator: <float4> / <int4>".
42
+ noReindex: true
37
43
  }
38
44
  },
39
45
  yugabytedb: {
@@ -43,7 +49,11 @@ const BACKEND_PROFILES = {
43
49
  noTablePartitioning: true,
44
50
  // Index builds are a distributed backfill that pg_stat_progress_create_index doesn't reflect,
45
51
  // so liveness would misread an in-flight build as dead. BAM falls back to the timeout instead.
46
- noIndexProgressView: true
52
+ noIndexProgressView: true,
53
+ // "REINDEX not supported yet" with or without CONCURRENTLY, and DocDB compaction owns
54
+ // reclamation. The bloat check runs but can never match: relpages and pg_relation_size() are
55
+ // 0 for every relation.
56
+ noReindex: true
47
57
  }
48
58
  },
49
59
  // No noIndexProgressView: pg-boss keeps its tables coordinator-local (it never calls
@@ -366,6 +376,7 @@ function getConfig(value) {
366
376
  config.migrate = ('migrate' in config) ? config.migrate : true;
367
377
  config.createSchema = ('createSchema' in config) ? config.createSchema : true;
368
378
  config.useListenNotify = ('useListenNotify' in config) ? config.useListenNotify : false;
379
+ config.reindex = ('reindex' in config) ? config.reindex : true;
369
380
  resolveBackend(config);
370
381
  applySchemaConfig(config);
371
382
  applyOpsConfig(config);
@@ -414,6 +425,11 @@ function resolveBackend(config) {
414
425
  if (config.__test__noIndexProgressView) {
415
426
  config.noIndexProgressView = true;
416
427
  }
428
+ // Test hook: exercise the detection-only reindex path (bloat is reported, never rebuilt) used by
429
+ // CockroachDB/YugabyteDB, on a plain Postgres instance.
430
+ if (config.__test__noReindex) {
431
+ config.noReindex = true;
432
+ }
417
433
  }
418
434
  // The character rules for the contents of a quoted name, as a predicate clause returned rather than
419
435
  // thrown, so the bare-name path can ask whether quoting would actually fix a name before
@@ -553,6 +569,23 @@ function applyOpsConfig(config) {
553
569
  assert(config.queueStatRetentionDays <= POLICY.MAX_RETENTION_DAYS, `configuration assert: queueStatRetentionDays cannot exceed ${POLICY.MAX_RETENTION_DAYS} days`);
554
570
  }
555
571
  config.queueStatRetentionDays = config.queueStatRetentionDays || 7;
572
+ validateReindexConfig(config);
573
+ }
574
+ function validateReindexConfig(config) {
575
+ assert(!('reindex' in config) || typeof config.reindex === 'boolean' || (typeof config.reindex === 'object' && config.reindex !== null), 'configuration assert: reindex must be a boolean or an options object');
576
+ if (typeof config.reindex === 'object' && config.reindex !== null) {
577
+ const { minPages, maxEntriesPerPage, minSizeRatio, maxIndexBytes, force } = config.reindex;
578
+ assert(minPages === undefined || (Number.isInteger(minPages) && minPages >= 0), 'configuration assert: reindex.minPages must be an integer >= 0');
579
+ assert(maxEntriesPerPage === undefined || (typeof maxEntriesPerPage === 'number' && maxEntriesPerPage > 0), 'configuration assert: reindex.maxEntriesPerPage must be a number > 0');
580
+ assert(minSizeRatio === undefined || (typeof minSizeRatio === 'number' && minSizeRatio >= 0), 'configuration assert: reindex.minSizeRatio must be a number >= 0');
581
+ assert(maxIndexBytes === undefined || (Number.isInteger(maxIndexBytes) && maxIndexBytes > 0), 'configuration assert: reindex.maxIndexBytes must be an integer > 0');
582
+ // force belongs to an explicit supervise() call, not to a background timer that would then
583
+ // rebuild every job index on every interval.
584
+ assert(force === undefined || force === false, 'configuration assert: reindex.force cannot be set in constructor options — pass it to supervise()');
585
+ }
586
+ assert(!('reindexIntervalSeconds' in config) || config.reindexIntervalSeconds >= 1, 'configuration assert: reindexIntervalSeconds must be at least every second');
587
+ config.reindexIntervalSeconds = config.reindexIntervalSeconds || POLICY.MAX_EXPIRATION_HOURS * 60 * 60;
588
+ assert(config.reindexIntervalSeconds / 60 / 60 <= POLICY.MAX_EXPIRATION_HOURS, `configuration assert: reindexIntervalSeconds cannot exceed ${POLICY.MAX_EXPIRATION_HOURS} hours`);
556
589
  }
557
590
  function validateDeletionConfig(config) {
558
591
  assert(!('deleteAfterSeconds' in config) || config.deleteAfterSeconds >= 0, 'configuration assert: deleteAfterSeconds must be at least 0 (0 disables deletion)');
package/dist/boss.d.ts CHANGED
@@ -11,7 +11,13 @@ declare class Boss extends EventEmitter implements types.EventsMixin {
11
11
  get maintaining(): boolean;
12
12
  start(): Promise<void>;
13
13
  stop(): Promise<void>;
14
- supervise(value?: string | types.QueueResult[]): Promise<void>;
14
+ supervise(value?: string | types.QueueResult[], options?: types.SuperviseOptions): Promise<void>;
15
+ /**
16
+ * The REINDEX statements this instance would run, for installations where it cannot run them
17
+ * itself. Unlike the background pass this applies no ownership filter and no size cap unless one
18
+ * is passed — the commands are for an operator, who may run them as a different role.
19
+ */
20
+ getReindexCommands(options?: types.ReindexOptions): Promise<string[]>;
15
21
  }
16
22
  export default Boss;
17
23
  //# sourceMappingURL=boss.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"boss.d.ts","sourceRoot":"","sources":["../src/boss.ts"],"names":[],"mappings":"AAAA,OAAO,YAAY,MAAM,aAAa,CAAA;AACtC,OAAO,KAAK,OAAO,MAAM,cAAc,CAAA;AAGvC,OAAO,KAAK,KAAK,MAAM,YAAY,CAAA;AAmBnC,cAAM,IAAK,SAAQ,YAAa,YAAW,KAAK,CAAC,WAAW;;IAW1D,MAAM;;;MAAS;gBAGb,EAAE,EAAE,KAAK,CAAC,SAAS,EACnB,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,KAAK,CAAC,0BAA0B;IAa1C,IAAI,WAAW,IAAK,OAAO,CAE1B;IAEK,KAAK;IAWL,IAAI;IA8FJ,SAAS,CAAE,KAAK,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC,WAAW,EAAE;CAgItD;AAED,eAAe,IAAI,CAAA"}
1
+ {"version":3,"file":"boss.d.ts","sourceRoot":"","sources":["../src/boss.ts"],"names":[],"mappings":"AAAA,OAAO,YAAY,MAAM,aAAa,CAAA;AACtC,OAAO,KAAK,OAAO,MAAM,cAAc,CAAA;AAGvC,OAAO,KAAK,KAAK,MAAM,YAAY,CAAA;AA0BnC,cAAM,IAAK,SAAQ,YAAa,YAAW,KAAK,CAAC,WAAW;;IAoB1D,MAAM;;;MAAS;gBAGb,EAAE,EAAE,KAAK,CAAC,SAAS,EACnB,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,KAAK,CAAC,0BAA0B;IAa1C,IAAI,WAAW,IAAK,OAAO,CAE1B;IAEK,KAAK;IAWL,IAAI;IA8FJ,SAAS,CAAE,KAAK,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC,WAAW,EAAE,EAAE,OAAO,CAAC,EAAE,KAAK,CAAC,gBAAgB;IAsSvF;;;;OAIG;IACG,kBAAkB,CAAE,OAAO,CAAC,EAAE,KAAK,CAAC,cAAc,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;CAwB7E;AAED,eAAe,IAAI,CAAA"}
package/dist/boss.js CHANGED
@@ -14,8 +14,14 @@ const WARNINGS = {
14
14
  };
15
15
  const WARNING_TYPES = {
16
16
  SLOW_QUERY: 'slow_query',
17
- QUEUE_BACKLOG: 'queue_backlog'
17
+ QUEUE_BACKLOG: 'queue_backlog',
18
+ INDEX_BLOAT: 'index_bloat'
18
19
  };
20
+ // SQLSTATE 25001 (active_sql_transaction): "REINDEX CONCURRENTLY cannot run inside a transaction
21
+ // block". Raised when a user-supplied adapter wraps executeSql in a transaction — a property of the
22
+ // adapter, not of this pass, so it disables rebuilds for the life of the instance rather than
23
+ // retrying every interval.
24
+ const IN_TRANSACTION_ERROR = '25001';
19
25
  class Boss extends EventEmitter {
20
26
  #stopped;
21
27
  #stopping;
@@ -26,6 +32,15 @@ class Boss extends EventEmitter {
26
32
  #manager;
27
33
  #slowQuerySeconds;
28
34
  #largeQueueSize;
35
+ // Set once a rebuild proves impossible on this connection (see IN_TRANSACTION_ERROR). Detection
36
+ // keeps running; only the DDL is abandoned.
37
+ #reindexUnavailable = null;
38
+ // Warn once per bloated index rather than on every pass. An index leaves the set as soon as it
39
+ // stops qualifying — rebuilt, dropped, or refilled — so a later episode warns again.
40
+ #warnedBloat = new Set();
41
+ // Local rate limit for passes that only report bloat, which deliberately leave the shared interval
42
+ // claim to whichever instance can act on it.
43
+ #detectOnly = 0;
29
44
  events = events;
30
45
  constructor(db, manager, config) {
31
46
  super();
@@ -124,7 +139,7 @@ class Boss extends EventEmitter {
124
139
  : plans.dropOldQueueStatsPartitions(this.#config.schema, this.#config.queueStatRetentionDays);
125
140
  await this.#executeQuery(sql);
126
141
  }
127
- async supervise(value) {
142
+ async supervise(value, options) {
128
143
  let queues;
129
144
  if (Array.isArray(value)) {
130
145
  queues = value;
@@ -163,6 +178,9 @@ class Boss extends EventEmitter {
163
178
  return;
164
179
  await this.#maintainWarnings();
165
180
  await this.#maintainQueueStats();
181
+ // Last in the pass: a rebuild is DDL that can run for seconds, so nothing time-sensitive
182
+ // (expiry, deletion, stats) should ever queue behind it.
183
+ await this.#reindex(Object.keys(queueGroups), options);
166
184
  }
167
185
  async #monitor(table, names) {
168
186
  if (this.#stopping)
@@ -223,5 +241,166 @@ class Boss extends EventEmitter {
223
241
  await this.#executeQuery(depSql);
224
242
  }
225
243
  }
244
+ // DDL runs outside the slow-query timer. A REINDEX is expected to take seconds — routing it
245
+ // through #executeQuery would emit a bogus slow_query warning on every rebuild.
246
+ async #executeDdl(sql) {
247
+ return unwrapSQLResult(await this.#db.executeSql(sql));
248
+ }
249
+ #resolveReindexOptions(options) {
250
+ const setting = options && 'reindex' in options ? options.reindex : this.#config.reindex;
251
+ if (setting === false)
252
+ return null;
253
+ if (setting === true || setting === undefined)
254
+ return {};
255
+ return setting;
256
+ }
257
+ /**
258
+ * Reports bloated job indexes and, unless disabled, rebuilds them with REINDEX INDEX
259
+ * CONCURRENTLY. See the notes in plans.ts for why the trigger is index density rather than
260
+ * elapsed time.
261
+ *
262
+ * Detection still runs where the rebuild cannot: a role that does not own the indexes, an adapter
263
+ * that wraps queries in a transaction, and `reindex: false` all still produce the `index_bloat`
264
+ * warning and can act on getReindexCommands(). The one exception is a backend that stores data
265
+ * outside PostgreSQL's heap — see the noReindex gate below.
266
+ */
267
+ async #reindex(tables, options) {
268
+ if (this.#stopping)
269
+ return;
270
+ // Skipped whole, detection included, on engines with no btree page bloat to find. Verified on
271
+ // CockroachDB v26.2 and YugabyteDB 2025.2: CockroachDB has no pg_relation_size() at all and
272
+ // rejects `reltuples / relpages` outright ("unsupported binary operator: <float4> / <int4>"),
273
+ // so running the check would throw once per interval; YugabyteDB answers but reports relpages
274
+ // and pg_relation_size as 0 for every relation, so nothing could ever match. Both store data in
275
+ // an LSM that compacts on its own, and both reject REINDEX in either form — CockroachDB with
276
+ // the hint "CockroachDB does not require reindexing."
277
+ if (this.#config.noReindex)
278
+ return;
279
+ const resolved = this.#resolveReindexOptions(options);
280
+ const force = !!resolved?.force;
281
+ const rebuilding = resolved !== null && !this.#reindexUnavailable;
282
+ // An explicit force is a request to run now; everything else waits for an interval.
283
+ //
284
+ // Which interval depends on whether this instance can do the work. The shared claim exists so
285
+ // exactly one instance in the cluster rebuilds per window — an instance that is only ever going
286
+ // to report bloat has no business taking it, or a peer configured to rebuild would find the
287
+ // window gone and skip the rebuild for a whole day. Detection-only passes throttle themselves
288
+ // locally instead, on the same interval.
289
+ if (!force) {
290
+ if (rebuilding) {
291
+ const claim = plans.trySetReindexTime(this.#config.schema, this.#config.reindexIntervalSeconds);
292
+ const { rows } = await this.#executeQuery(claim);
293
+ if (!rows.length)
294
+ return;
295
+ }
296
+ else {
297
+ if (Date.now() < this.#detectOnly)
298
+ return;
299
+ this.#detectOnly = Date.now() + this.#config.reindexIntervalSeconds * 1000;
300
+ }
301
+ }
302
+ if (this.#stopping)
303
+ return;
304
+ const scope = tables.length ? tables : undefined;
305
+ const detectSql = plans.getBloatedIndexes(this.#config.schema, scope, resolved ?? undefined);
306
+ const { rows: bloated } = await this.#executeQuery(detectSql);
307
+ let targets = [];
308
+ if (rebuilding) {
309
+ const maxIndexBytes = resolved.maxIndexBytes ?? plans.REINDEX_DEFAULTS.maxIndexBytes;
310
+ const candidates = force
311
+ ? (await this.#executeQuery(plans.getJobIndexes(this.#config.schema, scope))).rows
312
+ : bloated;
313
+ targets = candidates.filter((i) => i.owned && Number(i.bytes) <= maxIndexBytes);
314
+ if (targets.length) {
315
+ await this.#dropReindexLeftovers(scope);
316
+ }
317
+ }
318
+ const rebuilt = new Set();
319
+ const failed = new Map();
320
+ for (const target of targets) {
321
+ if (this.#stopping)
322
+ return;
323
+ try {
324
+ await this.#executeDdl(plans.reindexIndex(this.#config.schema, target.name));
325
+ rebuilt.add(target.name);
326
+ }
327
+ catch (err) {
328
+ const code = err?.code;
329
+ if (code === IN_TRANSACTION_ERROR) {
330
+ this.#reindexUnavailable = err.message;
331
+ failed.set(target.name, this.#reindexUnavailable);
332
+ // Every remaining index would fail identically — the transaction wrapper is a property of
333
+ // the adapter, not of this index.
334
+ break;
335
+ }
336
+ failed.set(target.name, err.message);
337
+ }
338
+ }
339
+ await this.#warnIndexBloat(bloated, rebuilt, failed, rebuilding);
340
+ }
341
+ // Invalid `*_ccnew` stubs from an interrupted REINDEX CONCURRENTLY. Best effort: a failure here
342
+ // must not stop the rebuilds, since the retry's own IF EXISTS handles the common case anyway.
343
+ async #dropReindexLeftovers(tables) {
344
+ try {
345
+ const { rows } = await this.#executeQuery(plans.getReindexLeftovers(this.#config.schema, tables, this.#config.noIndexProgressView));
346
+ for (const leftover of rows) {
347
+ if (this.#stopping)
348
+ return;
349
+ await this.#executeDdl(plans.dropIndexConcurrently(this.#config.schema, leftover.name));
350
+ }
351
+ }
352
+ catch (err) {
353
+ this.emit(events.error, err);
354
+ }
355
+ }
356
+ async #warnIndexBloat(bloated, rebuilt, failed, rebuilding) {
357
+ const stillBloated = new Set();
358
+ for (const index of bloated) {
359
+ // A rebuilt index is no longer a standing condition, and re-warning about it next episode is
360
+ // correct, so it never enters the warned set.
361
+ if (rebuilt.has(index.name))
362
+ continue;
363
+ stillBloated.add(index.name);
364
+ if (this.#warnedBloat.has(index.name))
365
+ continue;
366
+ // Ownership first: an index the role cannot touch was never a candidate, so it has no entry in
367
+ // `failed` no matter why the pass stopped. #reindexUnavailable comes next and covers the
368
+ // indexes the 25001 giveup skipped without attempting — they are neither failed nor rebuilt,
369
+ // and reporting a size cap they are nowhere near would point at the wrong knob.
370
+ const reason = failed.get(index.name) ??
371
+ (!index.owned
372
+ ? 'the connected role does not own the index'
373
+ : this.#reindexUnavailable ??
374
+ (!rebuilding
375
+ ? 'automatic reindexing is disabled'
376
+ : 'the index is larger than maxIndexBytes'));
377
+ await emitAndPersistWarning(this.#warningContext, WARNING_TYPES.INDEX_BLOAT, `Warning: index "${index.name}" is bloated (${Math.round(Number(index.bytes) / 1024 / 1024)} MB across ${index.pages} pages for ~${index.entries} live entries) and was not rebuilt: ${reason}. See getReindexCommands()`, index);
378
+ }
379
+ this.#warnedBloat = stillBloated;
380
+ }
381
+ /**
382
+ * The REINDEX statements this instance would run, for installations where it cannot run them
383
+ * itself. Unlike the background pass this applies no ownership filter and no size cap unless one
384
+ * is passed — the commands are for an operator, who may run them as a different role.
385
+ */
386
+ async getReindexCommands(options) {
387
+ // The catalog query reads pg_class.relpages and pg_relation_size(), which the heap-less engines
388
+ // either reject outright or answer with zeroes — same gate as #reindex, and there is nothing to
389
+ // rebuild on them anyway.
390
+ if (this.#config.noReindex)
391
+ return [];
392
+ const schema = this.#config.schema;
393
+ const sql = options?.force
394
+ ? plans.getJobIndexes(schema)
395
+ : plans.getBloatedIndexes(schema, undefined, options);
396
+ const { rows } = await this.#executeQuery(sql);
397
+ const targets = options?.maxIndexBytes === undefined
398
+ ? rows
399
+ : rows.filter((i) => Number(i.bytes) <= options.maxIndexBytes);
400
+ if (!targets.length)
401
+ return [];
402
+ const { rows: leftovers } = await this.#executeQuery(plans.getReindexLeftovers(schema, undefined, this.#config.noIndexProgressView, true));
403
+ return plans.buildReindexCommands(schema, targets, leftovers);
404
+ }
226
405
  }
227
406
  export default Boss;
package/dist/cli.js CHANGED
@@ -20,6 +20,7 @@ Commands:
20
20
  version Show current schema version
21
21
  doctor Check for schema/index drift against the expected shape
22
22
  plans Output SQL plans without executing
23
+ reindex Rebuild bloated job indexes (REINDEX INDEX CONCURRENTLY)
23
24
  rollback Rollback the last migration
24
25
 
25
26
  Options:
@@ -33,7 +34,8 @@ Options:
33
34
  --password, -p <pass> Database password
34
35
  --connection-string Full connection string (overrides other connection options)
35
36
  --ssl Enable SSL connection
36
- --dry-run Output SQL without executing (for plans command)
37
+ --dry-run Output SQL without executing (for plans and reindex commands)
38
+ --force Rebuild every job index, not just the bloated ones (reindex)
37
39
 
38
40
  Environment Variables:
39
41
  PGBOSS_DATABASE_URL Full connection string
@@ -123,7 +125,8 @@ function parseCliArgs() {
123
125
  password: { type: 'string', short: 'p' },
124
126
  'connection-string': { type: 'string' },
125
127
  ssl: { type: 'boolean' },
126
- 'dry-run': { type: 'boolean' }
128
+ 'dry-run': { type: 'boolean' },
129
+ force: { type: 'boolean' }
127
130
  },
128
131
  allowPositionals: true
129
132
  });
@@ -139,6 +142,7 @@ function parseCliArgs() {
139
142
  connectionString: values['connection-string'],
140
143
  ssl: values.ssl,
141
144
  dryRun: values['dry-run'],
145
+ force: values.force,
142
146
  command: positionals[0],
143
147
  subCommand: positionals[1]
144
148
  };
@@ -351,6 +355,24 @@ async function cmdDoctor(args) {
351
355
  for (const i of report.building)
352
356
  console.log(` ${i.table}.${i.name}`);
353
357
  }
358
+ // Index bloat is a runtime condition, not schema drift: the index matches its expected
359
+ // definition, it is just carrying pages it no longer needs. Printed regardless of overall
360
+ // status and never changes the exit code, same as extra indexes below.
361
+ try {
362
+ const { rows: bloated } = await db.executeSql(plans.getBloatedIndexes(schema));
363
+ if (bloated.length) {
364
+ console.log(`\n⚠ INDEX BLOAT (rebuild with "pg-boss reindex") (${bloated.length}):`);
365
+ for (const i of bloated) {
366
+ const mb = Math.round(Number(i.bytes) / 1024 / 1024);
367
+ console.log(` ${i.table}.${i.name} — ${mb} MB across ${i.pages} pages, ~${i.entries} live entries`);
368
+ if (!i.owned)
369
+ console.log(' note: the connected role does not own this index and cannot reindex it');
370
+ }
371
+ }
372
+ }
373
+ catch {
374
+ // Best effort — a role without catalog visibility should not fail the whole drift report.
375
+ }
354
376
  // Extra indexes are informational (a stale pg-boss index or a user-added one) — a warning, not
355
377
  // drift. Printed regardless of overall status; it never changes the exit code.
356
378
  if (report.extraIndexes.length) {
@@ -453,6 +475,96 @@ async function cmdDoctor(args) {
453
475
  await db.close();
454
476
  }
455
477
  }
478
+ // Bloated indexes are found and rebuilt directly here rather than through a PgBoss instance: the
479
+ // command must work against an installation this process does not otherwise manage, and starting an
480
+ // instance would also start workers, maintenance and migrations.
481
+ async function cmdReindex(args) {
482
+ const config = getConnectionConfig(args);
483
+ const schema = config.schema || plans.DEFAULT_SCHEMA;
484
+ const db = await createDb(config);
485
+ try {
486
+ const version = await getSchemaVersion(db, schema);
487
+ if (version === null) {
488
+ console.log(`pg-boss is not installed in schema "${schema}"`);
489
+ process.exitCode = 1;
490
+ return;
491
+ }
492
+ const sql = args.force ? plans.getJobIndexes(schema) : plans.getBloatedIndexes(schema);
493
+ let rows;
494
+ try {
495
+ ({ rows } = await db.executeSql(sql));
496
+ }
497
+ catch (err) {
498
+ // The check reads pg_class.relpages and pg_relation_size(). CockroachDB has neither (it
499
+ // rejects `reltuples / relpages` as an unsupported binary operator) and YugabyteDB reports
500
+ // zeroes for every relation. The CLI takes a connection string, not a backend profile, so
501
+ // there is nothing to gate on ahead of time — say what happened instead of surfacing a raw
502
+ // catalog error.
503
+ console.error(`Could not read index statistics from schema "${schema}": ${err.message}`);
504
+ console.error('The bloat check reads pg_class.relpages and pg_relation_size(), which CockroachDB and YugabyteDB do not provide.');
505
+ process.exitCode = 1;
506
+ return;
507
+ }
508
+ if (!rows.length) {
509
+ console.log(args.force
510
+ ? `No job indexes found in schema "${schema}"`
511
+ : `No bloated indexes found in schema "${schema}"`);
512
+ return;
513
+ }
514
+ // anyOwner for the printed list, which may be run as a different role; the execution path below
515
+ // filters ownership itself.
516
+ const { rows: leftovers } = await db.executeSql(plans.getReindexLeftovers(schema, undefined, false, args.dryRun));
517
+ if (args.dryRun) {
518
+ // Every index, ownership included: the printed SQL is for an operator, who may well run it as
519
+ // the role that does own them.
520
+ const commands = plans.buildReindexCommands(schema, rows, leftovers);
521
+ console.log(`-- SQL to rebuild ${rows.length} index(es) in schema "${schema}":`);
522
+ for (const command of commands)
523
+ console.log(`${command};`);
524
+ for (const index of rows.filter(i => !i.owned)) {
525
+ console.log(`-- note: "${index.name}" is not owned by ${config.user || 'the connected role'} and needs a role that can REINDEX it`);
526
+ }
527
+ return;
528
+ }
529
+ for (const index of rows) {
530
+ const mb = Math.round(Number(index.bytes) / 1024 / 1024);
531
+ console.log(` ${index.table}.${index.name} — ${mb} MB across ${index.pages} pages, ~${index.entries} live entries`);
532
+ }
533
+ // Executing is different from printing: REINDEX needs ownership, so an index this role cannot
534
+ // touch is reported up front rather than attempted for the sake of the server's error message.
535
+ const skipped = rows.filter(index => !index.owned);
536
+ const targets = rows.filter(index => index.owned);
537
+ for (const index of skipped) {
538
+ console.error(` ✗ ${index.name}\n the connected role does not own this index and cannot reindex it`);
539
+ }
540
+ if (!targets.length) {
541
+ process.exitCode = 1;
542
+ return;
543
+ }
544
+ const commands = plans.buildReindexCommands(schema, targets, leftovers);
545
+ console.log(`\nRebuilding ${targets.length} index(es)...`);
546
+ let failures = skipped.length;
547
+ for (const command of commands) {
548
+ try {
549
+ await db.executeSql(command);
550
+ console.log(` ✓ ${command}`);
551
+ }
552
+ catch (err) {
553
+ failures++;
554
+ console.error(` ✗ ${command}\n ${err.message}`);
555
+ }
556
+ }
557
+ if (failures) {
558
+ process.exitCode = 1;
559
+ }
560
+ else {
561
+ console.log('\n✓ Done');
562
+ }
563
+ }
564
+ finally {
565
+ await db.close();
566
+ }
567
+ }
456
568
  async function cmdPlans(args) {
457
569
  const fileConfig = loadConfigFile(args.config);
458
570
  const schema = args.schema || process.env.PGBOSS_SCHEMA || fileConfig.schema || plans.DEFAULT_SCHEMA;
@@ -527,6 +639,9 @@ async function main() {
527
639
  case 'plans':
528
640
  await cmdPlans(args);
529
641
  break;
642
+ case 'reindex':
643
+ await cmdReindex(args);
644
+ break;
530
645
  default:
531
646
  console.error(`Unknown command: ${args.command}`);
532
647
  console.error('Run "pg-boss --help" for available commands.');
package/dist/index.d.ts CHANGED
@@ -8,6 +8,12 @@ export declare function getConstructionPlans(schema?: string): string;
8
8
  export declare function getMigrationPlans(schema?: string, version?: number, options?: {
9
9
  partitionTables?: types.MigrationPartition[];
10
10
  }): string;
11
+ /**
12
+ * The catalog query pg-boss uses to find bloated job indexes, as SQL text. Runnable in psql with no
13
+ * pg-boss instance and no connection from this process. PostgreSQL only — the heap-less engines
14
+ * (CockroachDB, YugabyteDB) do not answer it.
15
+ */
16
+ export declare function getIndexBloatPlans(schema?: string, options?: types.IndexBloatOptions): string;
11
17
  export declare function getRollbackPlans(schema?: string, version?: number): string;
12
18
  export declare class PgBoss extends EventEmitter<types.PgBossEventMap> {
13
19
  #private;
@@ -68,7 +74,18 @@ export declare class PgBoss extends EventEmitter<types.PgBossEventMap> {
68
74
  isBamWorking(): boolean;
69
75
  isResolvingFlow(): boolean;
70
76
  isCheckingSkew(): boolean;
71
- supervise(name?: string): Promise<void>;
77
+ supervise(name?: string, options?: types.SuperviseOptions): Promise<void>;
78
+ /**
79
+ * The `REINDEX INDEX CONCURRENTLY` statements needed to rebuild the currently bloated job
80
+ * indexes, in the order they should be run, including any `DROP INDEX CONCURRENTLY` for stubs
81
+ * left by an interrupted rebuild.
82
+ *
83
+ * For installations where pg-boss cannot run them itself — a role that doesn't own the indexes,
84
+ * or an adapter that wraps queries in a transaction. Pass `{ force: true }` for every job index
85
+ * rather than only the bloated ones. Empty on CockroachDB and YugabyteDB, which have no btree
86
+ * bloat to reclaim and reject `REINDEX` in any form.
87
+ */
88
+ getReindexCommands(options?: types.ReindexOptions): Promise<string[]>;
72
89
  resolveFlow(): Promise<void>;
73
90
  getWipData(options?: {
74
91
  includeInternal?: boolean;
@@ -85,7 +102,7 @@ export declare class PgBoss extends EventEmitter<types.PgBossEventMap> {
85
102
  getBamEntries(): Promise<types.BamEntry[]>;
86
103
  getDb(): types.IDatabase;
87
104
  }
88
- export type { BackendProfile, BackendOptions, BamEntry, BamEvent, BamStatusSummary, CommandResponse, CompleteOptions, ConnectionOptions, ConstructorOptions, DatabaseOptions, FetchGroupConcurrencyOptions, DependencyRef, FetchOptions, FindJobsOptions, FlowJob, GroupConcurrencyConfig, GroupOptions, IDatabase as Db, InsertOptions, InvalidIndex, Job, JobFetchOptions, JobInsert, JobMatchStrategy, JobOptions, JobPollingOptions, JobResult, JobResultStatus, JobStates, Events, JobWithMetadata, MaintenanceOptions, ManagedIndex, MigrationPartition, AsyncMigrationCommand, MismatchedIndex, ManagedFunction, MismatchedFunction, TableColumnDrift, ConstraintDrift, EnumDrift, OffWorkOptions, PgBossEventMap, Queue, QueueOptions, QueuePolicy, QueueResult, QueueStats, QueueStatsOptions, RedriveOptions, Request, Schedule, ScheduleOptions, SchedulingOptions, SchemaDriftReport, SendOptions, StopOptions, UpdateOptions, UpdateQueueOptions, UpdateRequest, UpdateResponse, UpsertResponse, Warning, WipData, WorkConcurrencyOptions, WorkerState, WorkHandler, WorkOptions, WorkWithMetadataHandler, WorkHandlerFor, PerJobWorkHandler, PerJobWorkWithMetadataHandler, } from './types.ts';
105
+ export type { BackendProfile, BackendOptions, BamEntry, BamEvent, BamStatusSummary, CommandResponse, CompleteOptions, ConnectionOptions, ConstructorOptions, DatabaseOptions, FetchGroupConcurrencyOptions, DependencyRef, FetchOptions, FindJobsOptions, FlowJob, GroupConcurrencyConfig, GroupOptions, IDatabase as Db, InsertOptions, IndexBloat, IndexBloatOptions, InvalidIndex, Job, JobFetchOptions, JobInsert, JobMatchStrategy, JobOptions, JobPollingOptions, JobResult, JobResultStatus, JobStates, Events, JobWithMetadata, MaintenanceOptions, ManagedIndex, MigrationPartition, AsyncMigrationCommand, MismatchedIndex, ManagedFunction, MismatchedFunction, TableColumnDrift, ConstraintDrift, EnumDrift, OffWorkOptions, PgBossEventMap, Queue, QueueOptions, QueuePolicy, QueueResult, QueueStats, QueueStatsOptions, RedriveOptions, ReindexOptions, Request, Schedule, ScheduleOptions, SchedulingOptions, SchemaDriftReport, SendOptions, StopOptions, SuperviseOptions, UpdateOptions, UpdateQueueOptions, UpdateRequest, UpdateResponse, UpsertResponse, Warning, WipData, WorkConcurrencyOptions, WorkerState, WorkHandler, WorkOptions, WorkWithMetadataHandler, WorkHandlerFor, PerJobWorkHandler, PerJobWorkWithMetadataHandler, } from './types.ts';
89
106
  export type { JobSpyInterface, JobSpyState, JobDataSelector, JobSelector, SpyJob, } from './spy.ts';
90
107
  export { fromKnex, fromKysely, fromDrizzle, fromPrisma, fromPglite, } from './adapters/index.ts';
91
108
  export type { KnexTransactionLike, KyselyTransactionLike, DrizzleTransactionLike, DrizzleSqlTagLike, PrismaTransactionLike, PGliteLike, } from './adapters/index.ts';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -26,6 +26,14 @@ export function getConstructionPlans(schema) {
26
26
  export function getMigrationPlans(schema, version, options) {
27
27
  return Contractor.migrationPlans(schema, version, options);
28
28
  }
29
+ /**
30
+ * The catalog query pg-boss uses to find bloated job indexes, as SQL text. Runnable in psql with no
31
+ * pg-boss instance and no connection from this process. PostgreSQL only — the heap-less engines
32
+ * (CockroachDB, YugabyteDB) do not answer it.
33
+ */
34
+ export function getIndexBloatPlans(schema, options) {
35
+ return plans.getBloatedIndexes(schema || plans.DEFAULT_SCHEMA, undefined, options);
36
+ }
29
37
  export function getRollbackPlans(schema, version) {
30
38
  return Contractor.rollbackPlans(schema, version);
31
39
  }
@@ -342,8 +350,21 @@ export class PgBoss extends EventEmitter {
342
350
  isCheckingSkew() {
343
351
  return this.#timekeeper.checkingSkew;
344
352
  }
345
- supervise(name) {
346
- return this.#boss.supervise(name);
353
+ supervise(name, options) {
354
+ return this.#boss.supervise(name, options);
355
+ }
356
+ /**
357
+ * The `REINDEX INDEX CONCURRENTLY` statements needed to rebuild the currently bloated job
358
+ * indexes, in the order they should be run, including any `DROP INDEX CONCURRENTLY` for stubs
359
+ * left by an interrupted rebuild.
360
+ *
361
+ * For installations where pg-boss cannot run them itself — a role that doesn't own the indexes,
362
+ * or an adapter that wraps queries in a transaction. Pass `{ force: true }` for every job index
363
+ * rather than only the bloated ones. Empty on CockroachDB and YugabyteDB, which have no btree
364
+ * bloat to reclaim and reject `REINDEX` in any form.
365
+ */
366
+ getReindexCommands(options) {
367
+ return this.#boss.getReindexCommands(options);
347
368
  }
348
369
  // Force an immediate flow-resolution pass (unblock dependents of completed jobs) instead of
349
370
  // waiting for the next background poll. Mirrors supervise() for on-demand maintenance.