pg-boss 12.35.1 → 12.37.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 +2 -1
- package/dist/attorney.d.ts.map +1 -1
- package/dist/attorney.js +26 -0
- package/dist/boss.d.ts.map +1 -1
- package/dist/boss.js +35 -4
- package/dist/cli.js +8 -2
- package/dist/contractor.d.ts +1 -0
- package/dist/contractor.d.ts.map +1 -1
- package/dist/contractor.js +4 -0
- package/dist/db.d.ts +1 -0
- package/dist/db.d.ts.map +1 -1
- package/dist/db.js +14 -3
- package/dist/index.d.ts +11 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +88 -9
- package/dist/latency.d.ts +15 -0
- package/dist/latency.d.ts.map +1 -0
- package/dist/latency.js +45 -0
- package/dist/manager.d.ts.map +1 -1
- package/dist/manager.js +296 -75
- package/dist/migrationStore.d.ts.map +1 -1
- package/dist/migrationStore.js +194 -0
- package/dist/nurse.d.ts +20 -0
- package/dist/nurse.d.ts.map +1 -0
- package/dist/nurse.js +287 -0
- package/dist/plans.d.ts +27 -2
- package/dist/plans.d.ts.map +1 -1
- package/dist/plans.js +556 -55
- package/dist/registrar.d.ts +16 -0
- package/dist/registrar.d.ts.map +1 -0
- package/dist/registrar.js +226 -0
- package/dist/schema.json +514 -2
- package/dist/telemetry.d.ts +65 -0
- package/dist/telemetry.d.ts.map +1 -0
- package/dist/telemetry.js +349 -0
- package/dist/timekeeper.d.ts +4 -1
- package/dist/timekeeper.d.ts.map +1 -1
- package/dist/timekeeper.js +22 -5
- package/dist/types.d.ts +213 -8
- package/dist/types.d.ts.map +1 -1
- package/dist/worker.d.ts +1 -0
- package/dist/worker.d.ts.map +1 -1
- package/dist/worker.js +2 -0
- package/package.json +14 -5
package/README.md
CHANGED
|
@@ -51,8 +51,9 @@ This will likely cater the most to teams already familiar with the simplicity of
|
|
|
51
51
|
* Pub/sub API for fan-out queue relationships
|
|
52
52
|
* SQL support for non-Node.js runtimes for most operations
|
|
53
53
|
* Serverless function compatible
|
|
54
|
+
* [OpenTelemetry](https://pgboss.io/opentelemetry) traces and metrics
|
|
54
55
|
* Multi-master compatible (for example, in a Kubernetes ReplicaSet)
|
|
55
|
-
* [Additional database backends](https://pgboss.io/database-backends) for Postgres-based databases such as CockroachDB
|
|
56
|
+
* [Additional database backends](https://pgboss.io/database-backends) for Postgres-based databases such as CockroachDB and Citus. Or, use embedded PGlite for running entirely in-process.
|
|
56
57
|
|
|
57
58
|
## CLI
|
|
58
59
|
|
package/dist/attorney.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"attorney.d.ts","sourceRoot":"","sources":["../src/attorney.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,KAAK,KAAK,MAAM,YAAY,CAAA;AAExC,QAAA,MAAM,MAAM;;;;CAIX,CAAA;AAKD,QAAA,MAAM,mBAAmB,6RAcf,CAAA;AA+EV,iBAAS,iBAAiB,CAAE,MAAM,GAAE,GAAQ,QAc3C;AAiBD,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,CAgCA;AAqBD,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,
|
|
1
|
+
{"version":3,"file":"attorney.d.ts","sourceRoot":"","sources":["../src/attorney.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,KAAK,KAAK,MAAM,YAAY,CAAA;AAExC,QAAA,MAAM,MAAM;;;;CAIX,CAAA;AAKD,QAAA,MAAM,mBAAmB,6RAcf,CAAA;AA+EV,iBAAS,iBAAiB,CAAE,MAAM,GAAE,GAAQ,QAc3C;AAiBD,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,CAgCA;AAqBD,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,CA4B9F;AA4JD,iBAAS,wBAAwB,CAAE,IAAI,EAAE,MAAM,QAiC9C;AAED,iBAAS,eAAe,CAAE,IAAI,EAAE,MAAM,QAIrC;AAED,iBAAS,SAAS,CAAE,GAAG,EAAE,MAAM,QAI9B;AA+LD,OAAO,EACL,SAAS,EACT,mBAAmB,EACnB,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
|
@@ -422,7 +422,9 @@ function getConfig(value) {
|
|
|
422
422
|
applyScheduleConfig(config);
|
|
423
423
|
applyBamConfig(config);
|
|
424
424
|
applyFlowConfig(config);
|
|
425
|
+
applyInstanceConfig(config);
|
|
425
426
|
validateWarningConfig(config);
|
|
427
|
+
validateOpenTelemetryConfig(config);
|
|
426
428
|
return config;
|
|
427
429
|
}
|
|
428
430
|
const CLOCK_METHODS = ['now', 'setTimeout', 'clearTimeout', 'setInterval', 'clearInterval'];
|
|
@@ -441,6 +443,25 @@ function applySchemaConfig(config) {
|
|
|
441
443
|
}
|
|
442
444
|
config.schema = config.schema || DEFAULT_SCHEMA;
|
|
443
445
|
}
|
|
446
|
+
function applyInstanceConfig(config) {
|
|
447
|
+
config.registerInstance = ('registerInstance' in config) ? config.registerInstance !== false : true;
|
|
448
|
+
assert(!('instanceName' in config) || config.instanceName === undefined || (typeof config.instanceName === 'string' && config.instanceName.length > 0), 'configuration assert: instanceName must be a non-empty string');
|
|
449
|
+
assert(!('instanceHeartbeatSeconds' in config) || config.instanceHeartbeatSeconds === undefined ||
|
|
450
|
+
(Number.isInteger(config.instanceHeartbeatSeconds) && config.instanceHeartbeatSeconds >= 1 && config.instanceHeartbeatSeconds <= 3600), 'configuration assert: instanceHeartbeatSeconds must be an integer from 1 to 3600');
|
|
451
|
+
config.instanceHeartbeatSeconds = config.instanceHeartbeatSeconds || 30;
|
|
452
|
+
}
|
|
453
|
+
function validateOpenTelemetryConfig(config) {
|
|
454
|
+
const otel = config.openTelemetry;
|
|
455
|
+
if (otel == null)
|
|
456
|
+
return;
|
|
457
|
+
assert(typeof otel === 'object', 'configuration assert: openTelemetry must be an object');
|
|
458
|
+
for (const key of ['enabled', 'propagateContext']) {
|
|
459
|
+
assert(otel[key] === undefined || typeof otel[key] === 'boolean', `configuration assert: openTelemetry.${key} must be a boolean`);
|
|
460
|
+
}
|
|
461
|
+
assert(otel.tracerProvider === undefined || typeof otel.tracerProvider?.getTracer === 'function', 'configuration assert: openTelemetry.tracerProvider must implement getTracer()');
|
|
462
|
+
assert(otel.meterProvider === undefined || typeof otel.meterProvider?.getMeter === 'function', 'configuration assert: openTelemetry.meterProvider must implement getMeter()');
|
|
463
|
+
assert(otel.propagator === undefined || (typeof otel.propagator?.inject === 'function' && typeof otel.propagator?.extract === 'function'), 'configuration assert: openTelemetry.propagator must implement inject() and extract()');
|
|
464
|
+
}
|
|
444
465
|
function validateWarningConfig(config) {
|
|
445
466
|
assert(!('warningQueueSize' in config) || config.warningQueueSize >= 1, 'configuration assert: warningQueueSize must be at least 1');
|
|
446
467
|
assert(!('warningSlowQuerySeconds' in config) || config.warningSlowQuerySeconds >= 1, 'configuration assert: warningSlowQuerySeconds must be at least 1');
|
|
@@ -456,6 +477,11 @@ function resolveBackend(config) {
|
|
|
456
477
|
assert(backend in BACKEND_PROFILES, `configuration assert: backend must be one of ${Object.keys(BACKEND_PROFILES).join(', ')}`);
|
|
457
478
|
config.backend = backend;
|
|
458
479
|
const { flags } = BACKEND_PROFILES[backend];
|
|
480
|
+
// A DeprecationWarning, like the deprecated fetch options in manager.ts: dropping the profile is a
|
|
481
|
+
// configuration change a developer makes, not a condition an operator watches.
|
|
482
|
+
if (backend === 'yugabytedb') {
|
|
483
|
+
process.emitWarning("backend: 'yugabytedb' is deprecated and will be rejected in the next major. YugabyteDB is not supported: releases are not tested against it and upgrades do not work there. See https://pgboss.io/database-backends#not-supported-yugabytedb", 'DeprecationWarning', 'PGBOSS_DEP_YUGABYTEDB');
|
|
484
|
+
}
|
|
459
485
|
for (const flag of COMPATIBILITY_FLAGS) {
|
|
460
486
|
config[flag] = flags[flag] ?? false;
|
|
461
487
|
}
|
package/dist/boss.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"boss.d.ts","sourceRoot":"","sources":["../src/boss.ts"],"names":[],"mappings":"AAAA,OAAO,YAAY,MAAM,aAAa,CAAA;AAEtC,OAAO,KAAK,OAAO,MAAM,cAAc,CAAA;AAGvC,OAAO,KAAK,KAAK,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"boss.d.ts","sourceRoot":"","sources":["../src/boss.ts"],"names":[],"mappings":"AAAA,OAAO,YAAY,MAAM,aAAa,CAAA;AAEtC,OAAO,KAAK,OAAO,MAAM,cAAc,CAAA;AAGvC,OAAO,KAAK,KAAK,MAAM,YAAY,CAAA;AAkInC,cAAM,IAAK,SAAQ,YAAa,YAAW,KAAK,CAAC,WAAW;;IAsC1D,MAAM;;;MAAS;gBAGb,EAAE,EAAE,KAAK,CAAC,SAAS,EACnB,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,KAAK,CAAC,0BAA0B;IAa1C,IAAI,WAAW,IAAK,OAAO,CAE1B;IAIK,KAAK;IAiBL,IAAI;IAoHJ,SAAS,CAAE,KAAK,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC,WAAW,EAAE,EAAE,OAAO,CAAC,EAAE,KAAK,CAAC,gBAAgB;IA2tBvF;;;;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
|
@@ -40,6 +40,22 @@ const XMIN_HOLDERS = {
|
|
|
40
40
|
standbys: 'a standby with hot_standby_feedback enabled',
|
|
41
41
|
prepared: 'a prepared transaction'
|
|
42
42
|
};
|
|
43
|
+
// The names pg-boss gives the pools it creates: 'pgboss:<id>' for a registered instance, and
|
|
44
|
+
// 'pgboss' for one that does not register or predates the registry.
|
|
45
|
+
function isPgBossName(name) {
|
|
46
|
+
return name === 'pgboss' || !!name?.startsWith('pgboss:');
|
|
47
|
+
}
|
|
48
|
+
// Whether a backend's application_name says it is pg-boss, as this connection is: the same name, or
|
|
49
|
+
// both one of pg-boss's own names. Either form on either side, so an instance still on 'pgboss'
|
|
50
|
+
// during a rolling upgrade reads as pg-boss to an upgraded one. Another pg-boss instance pinning the
|
|
51
|
+
// horizon takes the same fix as this one doing it.
|
|
52
|
+
function isPgBossHolder(app, self) {
|
|
53
|
+
if (!app)
|
|
54
|
+
return false;
|
|
55
|
+
if (app === self)
|
|
56
|
+
return true;
|
|
57
|
+
return isPgBossName(app) && isPgBossName(self);
|
|
58
|
+
}
|
|
43
59
|
// Name the holder as specifically as the catalog allowed. Falls back to the holder class when the
|
|
44
60
|
// source is not a backend (a replication slot has no pid to report) or when no backend row came
|
|
45
61
|
// back, so the warning never loses the description it had before.
|
|
@@ -64,7 +80,9 @@ function describeXminHolder(source, row) {
|
|
|
64
80
|
? 'a backend with no application_name'
|
|
65
81
|
: app === row.selfApplicationName
|
|
66
82
|
? "this application's own connection"
|
|
67
|
-
:
|
|
83
|
+
: isPgBossHolder(app, row.selfApplicationName)
|
|
84
|
+
? "another pg-boss instance's connection"
|
|
85
|
+
: 'another application';
|
|
68
86
|
return `${who} (${where}) has held a transaction open ${open}`;
|
|
69
87
|
}
|
|
70
88
|
// SQLSTATE 25001 (active_sql_transaction): "REINDEX CONCURRENTLY cannot run inside a transaction
|
|
@@ -204,6 +222,18 @@ class Boss extends EventEmitter {
|
|
|
204
222
|
const sql = plans.deleteOldWarnings(this.#config.schema, this.#config.warningRetentionDays);
|
|
205
223
|
await this.#executeQuery(sql);
|
|
206
224
|
}
|
|
225
|
+
// Whether or not this instance registers: the registry is the database's, not this instance's.
|
|
226
|
+
// Best effort: a failure is emitted and the pass goes on to the reindex, since a role granted
|
|
227
|
+
// privileges table by table may have none on the instance table yet.
|
|
228
|
+
async #maintainInstances() {
|
|
229
|
+
try {
|
|
230
|
+
await this.#executeQuery(plans.deleteOldInstances(this.#config.schema, plans.INSTANCE_RETENTION_DAYS));
|
|
231
|
+
await this.#executeQuery(plans.trimDeadInstances(this.#config.schema, plans.INSTANCE_DEAD_KEPT));
|
|
232
|
+
}
|
|
233
|
+
catch (err) {
|
|
234
|
+
this.emit(events.error, err);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
207
237
|
async #ensureQueueStatsPartitions() {
|
|
208
238
|
const sql = plans.ensureQueueStatsPartitions(this.#config.schema);
|
|
209
239
|
await this.#executeQuery(sql);
|
|
@@ -286,6 +316,7 @@ class Boss extends EventEmitter {
|
|
|
286
316
|
await this.#checkVacuum();
|
|
287
317
|
await this.#maintainWarnings();
|
|
288
318
|
await this.#maintainQueueStats();
|
|
319
|
+
await this.#maintainInstances();
|
|
289
320
|
// Last in the pass: a rebuild is DDL that can run for seconds, so nothing time-sensitive
|
|
290
321
|
// (expiry, deletion, stats) should ever queue behind it.
|
|
291
322
|
await this.#reindex(Object.keys(queueGroups), options);
|
|
@@ -614,14 +645,14 @@ class Boss extends EventEmitter {
|
|
|
614
645
|
holder: describeXminHolder(holder.source, horizon.row),
|
|
615
646
|
holderClass: XMIN_HOLDERS[holder.source],
|
|
616
647
|
// Null unless the holder is a backend this role could read a row for. `self` says whether it
|
|
617
|
-
//
|
|
618
|
-
// external reporting tool pinning it have opposite fixes.
|
|
648
|
+
// is pg-boss: this connection's application_name, or another pg-boss instance's. A pg-boss
|
|
649
|
+
// instance pinning its own horizon and an external reporting tool pinning it have opposite fixes.
|
|
619
650
|
holderPid: backend?.pid ?? null,
|
|
620
651
|
holderApplicationName: backend?.applicationName ?? null,
|
|
621
652
|
holderUserName: backend?.userName ?? null,
|
|
622
653
|
holderState: backend?.state ?? null,
|
|
623
654
|
holderTransactionSeconds: backend?.xactSeconds ?? null,
|
|
624
|
-
self: backend ? backend.applicationName
|
|
655
|
+
self: backend ? isPgBossHolder(backend.applicationName || null, horizon.row.selfApplicationName) : null,
|
|
625
656
|
// Backends whose transaction this role is not allowed to time. Non-zero means the picture is
|
|
626
657
|
// partial, whether or not a holder was named.
|
|
627
658
|
opaqueBackends: opaque,
|
package/dist/cli.js
CHANGED
|
@@ -35,7 +35,7 @@ Options:
|
|
|
35
35
|
--password, -p <pass> Database password
|
|
36
36
|
--connection-string Full connection string (overrides other connection options)
|
|
37
37
|
--ssl Enable SSL connection
|
|
38
|
-
--backend <profile> Database backend: postgres (default), cockroachdb,
|
|
38
|
+
--backend <profile> Database backend: postgres (default), cockroachdb, citus.
|
|
39
39
|
Non-postgres backends need this to emit schema they accept.
|
|
40
40
|
--dry-run Output SQL without executing (for plans and reindex commands)
|
|
41
41
|
--force Rebuild every job index, not just the bloated ones (reindex)
|
|
@@ -69,6 +69,7 @@ Examples:
|
|
|
69
69
|
pg-boss migrate --schema my_schema
|
|
70
70
|
pg-boss create --connection-string postgres://user:pass@localhost/db
|
|
71
71
|
pg-boss plans migrate --dry-run
|
|
72
|
+
pg-boss plans uninstall --schema my_schema
|
|
72
73
|
pg-boss migrate --backend cockroachdb --connection-string postgres://root@localhost:26257/db
|
|
73
74
|
pg-boss version
|
|
74
75
|
PGBOSS_DATABASE_URL=postgres://localhost/mydb pg-boss migrate
|
|
@@ -708,9 +709,14 @@ async function cmdPlans(args) {
|
|
|
708
709
|
console.log(`-- SQL to rollback pg-boss from version ${schemaVersion} to ${schemaVersion - 1}:`);
|
|
709
710
|
console.log(migrationStore.rollback(schema, schemaVersion, migrationStore.getAllForConfig(config), config.noAdvisoryLocks));
|
|
710
711
|
break;
|
|
712
|
+
case 'uninstall':
|
|
713
|
+
console.log('-- SQL to remove every pg-boss object from a schema it shares with other objects.');
|
|
714
|
+
console.log(`-- If pg-boss has the schema to itself, DROP SCHEMA ${schema} CASCADE does the same.`);
|
|
715
|
+
console.log(plans.uninstall(schema, !config.noTablePartitioning));
|
|
716
|
+
break;
|
|
711
717
|
default:
|
|
712
718
|
console.error(`Unknown plans subcommand: ${subCommand}`);
|
|
713
|
-
console.error('Available: create, migrate, rollback');
|
|
719
|
+
console.error('Available: create, migrate, rollback, uninstall');
|
|
714
720
|
process.exit(1);
|
|
715
721
|
}
|
|
716
722
|
}
|
package/dist/contractor.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ export declare function installConfig<T extends {
|
|
|
5
5
|
declare class Contractor {
|
|
6
6
|
static constructionPlans(schema?: string, options?: types.ConstructionPlanOptions): string;
|
|
7
7
|
static migrationPlans(schema?: string, version?: number, options?: types.MigrationPlanOptions): string;
|
|
8
|
+
static uninstallPlans(schema?: string, options?: types.PlanOptions): string;
|
|
8
9
|
static rollbackPlans(schema?: string, version?: number, options?: types.PlanOptions): string;
|
|
9
10
|
private config;
|
|
10
11
|
private db;
|
package/dist/contractor.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"contractor.d.ts","sourceRoot":"","sources":["../src/contractor.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,KAAK,KAAK,MAAM,YAAY,CAAA;AAsBxC,wBAAsB,aAAa,CAAC,CAAC,SAAS;IAAE,kBAAkB,CAAC,EAAE,OAAO,CAAA;CAAE,EAAG,EAAE,EAAE,KAAK,CAAC,SAAS,EAAE,MAAM,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAO3H;AAED,cAAM,UAAU;IACd,MAAM,CAAC,iBAAiB,CAAE,MAAM,SAAuB,EAAE,OAAO,GAAE,KAAK,CAAC,uBAA4B;IAcpG,MAAM,CAAC,cAAc,CAAE,MAAM,SAAuB,EAAE,OAAO,SAAoB,EAAE,OAAO,GAAE,KAAK,CAAC,oBAAyB;IAS3H,MAAM,CAAC,aAAa,CAAE,MAAM,SAAuB,EAAE,OAAO,SAAgB,EAAE,OAAO,GAAE,KAAK,CAAC,WAAgB;IAM7G,OAAO,CAAC,MAAM,CAAkC;IAChD,OAAO,CAAC,EAAE,CAAiB;IAC3B,OAAO,CAAC,UAAU,CAAmB;gBAExB,EAAE,EAAE,KAAK,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,CAAC,0BAA0B;IAgBpE,aAAa;IAKb,WAAW;IAKX,KAAK;YAsBG,yBAAyB;IAkCjC,WAAW,CAAE,OAAO,GAAE;QAAE,aAAa,CAAC,EAAE,OAAO,CAAA;KAAO,GAAG,OAAO,CAAC,KAAK,CAAC,iBAAiB,CAAC;IAwHzF,mBAAmB,IAAK,OAAO,CAAC,OAAO,CAAC;IASxC,oBAAoB,IAAK,OAAO,CAAC,IAAI,CAAC;IAItC,KAAK;IAcL,MAAM;IASN,OAAO,CAAE,OAAO,EAAE,MAAM;IASxB,IAAI,CAAE,OAAO,EAAE,MAAM;IAKrB,QAAQ,CAAE,OAAO,EAAE,MAAM;CAIhC;AAED,eAAe,UAAU,CAAA"}
|
|
1
|
+
{"version":3,"file":"contractor.d.ts","sourceRoot":"","sources":["../src/contractor.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,KAAK,KAAK,MAAM,YAAY,CAAA;AAsBxC,wBAAsB,aAAa,CAAC,CAAC,SAAS;IAAE,kBAAkB,CAAC,EAAE,OAAO,CAAA;CAAE,EAAG,EAAE,EAAE,KAAK,CAAC,SAAS,EAAE,MAAM,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAO3H;AAED,cAAM,UAAU;IACd,MAAM,CAAC,iBAAiB,CAAE,MAAM,SAAuB,EAAE,OAAO,GAAE,KAAK,CAAC,uBAA4B;IAcpG,MAAM,CAAC,cAAc,CAAE,MAAM,SAAuB,EAAE,OAAO,SAAoB,EAAE,OAAO,GAAE,KAAK,CAAC,oBAAyB;IAS3H,MAAM,CAAC,cAAc,CAAE,MAAM,SAAuB,EAAE,OAAO,GAAE,KAAK,CAAC,WAAgB;IAMrF,MAAM,CAAC,aAAa,CAAE,MAAM,SAAuB,EAAE,OAAO,SAAgB,EAAE,OAAO,GAAE,KAAK,CAAC,WAAgB;IAM7G,OAAO,CAAC,MAAM,CAAkC;IAChD,OAAO,CAAC,EAAE,CAAiB;IAC3B,OAAO,CAAC,UAAU,CAAmB;gBAExB,EAAE,EAAE,KAAK,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,CAAC,0BAA0B;IAgBpE,aAAa;IAKb,WAAW;IAKX,KAAK;YAsBG,yBAAyB;IAkCjC,WAAW,CAAE,OAAO,GAAE;QAAE,aAAa,CAAC,EAAE,OAAO,CAAA;KAAO,GAAG,OAAO,CAAC,KAAK,CAAC,iBAAiB,CAAC;IAwHzF,mBAAmB,IAAK,OAAO,CAAC,OAAO,CAAC;IASxC,oBAAoB,IAAK,OAAO,CAAC,IAAI,CAAC;IAItC,KAAK;IAcL,MAAM;IASN,OAAO,CAAE,OAAO,EAAE,MAAM;IASxB,IAAI,CAAE,OAAO,EAAE,MAAM;IAKrB,QAAQ,CAAE,OAAO,EAAE,MAAM;CAIhC;AAED,eAAe,UAAU,CAAA"}
|
package/dist/contractor.js
CHANGED
|
@@ -48,6 +48,10 @@ class Contractor {
|
|
|
48
48
|
// live connection can pass partition metadata to fan the builds out across partitions.
|
|
49
49
|
return migrationStore.migrate(schema, version, migrationStore.getAllForConfig(config), config.noAdvisoryLocks, { inlineAsync: true, partitionTables: options.partitionTables });
|
|
50
50
|
}
|
|
51
|
+
static uninstallPlans(schema = plans.DEFAULT_SCHEMA, options = {}) {
|
|
52
|
+
const config = planConfig(schema, options.backend);
|
|
53
|
+
return plans.uninstall(schema, !config.noTablePartitioning);
|
|
54
|
+
}
|
|
51
55
|
static rollbackPlans(schema = plans.DEFAULT_SCHEMA, version = schemaVersion, options = {}) {
|
|
52
56
|
const config = planConfig(schema, options.backend);
|
|
53
57
|
return migrationStore.rollback(schema, version, migrationStore.getAllForConfig(config), config.noAdvisoryLocks);
|
package/dist/db.d.ts
CHANGED
|
@@ -15,6 +15,7 @@ declare class Db extends EventEmitter implements types.IDatabase, types.EventsMi
|
|
|
15
15
|
};
|
|
16
16
|
open(): Promise<void>;
|
|
17
17
|
close(): Promise<void>;
|
|
18
|
+
poolCounts(): types.PoolCounts | null;
|
|
18
19
|
setSessionStatements(statements: string[]): Promise<void>;
|
|
19
20
|
executeSql(text: string, values?: unknown[]): Promise<import("pg").QueryResult<any>>;
|
|
20
21
|
listen(channel: string, onNotification: (payload: string) => void, onReconnect: () => void): Promise<types.ListenHandle>;
|
package/dist/db.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"db.d.ts","sourceRoot":"","sources":["../src/db.ts"],"names":[],"mappings":"AAAA,OAAO,YAAY,MAAM,aAAa,CAAA;AAItC,OAAO,KAAK,KAAK,KAAK,MAAM,YAAY,CAAA;AAaxC,eAAO,MAAM,+BAA+B,OAAO,CAAA;AAEnD,cAAM,EAAG,SAAQ,YAAa,YAAW,KAAK,CAAC,SAAS,EAAE,KAAK,CAAC,WAAW;IACzE,OAAO,CAAC,IAAI,CAAU;IACtB,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,KAAK,CAAa;IAG1B,OAAO,CAAC,iBAAiB,CAAe;IAGxC,MAAM,EAAE,OAAO,CAAA;gBAEF,MAAM,EAAE,KAAK,CAAC,eAAe,GAAG;QAAE,KAAK,CAAC,EAAE,KAAK,CAAC,KAAK,CAAA;KAAE;IAcpE,MAAM;;MAEL;IAEK,IAAI;IAgBJ,KAAK;
|
|
1
|
+
{"version":3,"file":"db.d.ts","sourceRoot":"","sources":["../src/db.ts"],"names":[],"mappings":"AAAA,OAAO,YAAY,MAAM,aAAa,CAAA;AAItC,OAAO,KAAK,KAAK,KAAK,MAAM,YAAY,CAAA;AAaxC,eAAO,MAAM,+BAA+B,OAAO,CAAA;AAEnD,cAAM,EAAG,SAAQ,YAAa,YAAW,KAAK,CAAC,SAAS,EAAE,KAAK,CAAC,WAAW;IACzE,OAAO,CAAC,IAAI,CAAU;IACtB,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,KAAK,CAAa;IAG1B,OAAO,CAAC,iBAAiB,CAAe;IAGxC,MAAM,EAAE,OAAO,CAAA;gBAEF,MAAM,EAAE,KAAK,CAAC,eAAe,GAAG;QAAE,KAAK,CAAC,EAAE,KAAK,CAAC,KAAK,CAAA;KAAE;IAcpE,MAAM;;MAEL;IAEK,IAAI;IAgBJ,KAAK;IAQX,UAAU,IAAK,KAAK,CAAC,UAAU,GAAG,IAAI;IAUhC,oBAAoB,CAAE,UAAU,EAAE,MAAM,EAAE;IAoC1C,UAAU,CAAE,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE;IAqB5C,MAAM,CACV,OAAO,EAAE,MAAM,EACf,cAAc,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,EACzC,WAAW,EAAE,MAAM,IAAI,GACtB,OAAO,CAAC,KAAK,CAAC,YAAY,CAAC;IA2JxB,gBAAgB,IAAK,OAAO,CAAC,KAAK,CAAC,iBAAiB,CAAC;IAsFrD,eAAe,CAAC,CAAC,EAAG,EAAE,EAAE,CAAC,EAAE,EAAE,KAAK,CAAC,SAAS,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;CAY/E;AAED,eAAe,EAAE,CAAA"}
|
package/dist/db.js
CHANGED
|
@@ -55,6 +55,17 @@ class Db extends EventEmitter {
|
|
|
55
55
|
await this.pool.end();
|
|
56
56
|
}
|
|
57
57
|
}
|
|
58
|
+
// The pool's size and use, for the instance registry's heartbeat. Null before open() and after close().
|
|
59
|
+
poolCounts() {
|
|
60
|
+
if (!this.opened)
|
|
61
|
+
return null;
|
|
62
|
+
return {
|
|
63
|
+
max: this.pool.options.max ?? 10,
|
|
64
|
+
total: this.pool.totalCount,
|
|
65
|
+
idle: this.pool.idleCount,
|
|
66
|
+
waiting: this.pool.waitingCount
|
|
67
|
+
};
|
|
68
|
+
}
|
|
58
69
|
async setSessionStatements(statements) {
|
|
59
70
|
// Clearing is always safe: the statements it would have run are the ones already applied, and
|
|
60
71
|
// undoing them is the caller's job.
|
|
@@ -86,7 +97,7 @@ class Db extends EventEmitter {
|
|
|
86
97
|
}
|
|
87
98
|
}
|
|
88
99
|
async executeSql(text, values) {
|
|
89
|
-
assert(this.opened, 'Database not opened. Call
|
|
100
|
+
assert(this.opened, 'Database not opened. Call start() before using pg-boss, or again after stop().');
|
|
90
101
|
// if (this.config.debug === true) {
|
|
91
102
|
// console.log(`${new Date().toISOString()}: DEBUG SQL`)
|
|
92
103
|
// console.log(text)
|
|
@@ -103,7 +114,7 @@ class Db extends EventEmitter {
|
|
|
103
114
|
// drops and lost subscriptions. The client reconnects with capped backoff, re-runs LISTEN,
|
|
104
115
|
// then calls onReconnect so the caller can recover missed messages.
|
|
105
116
|
async listen(channel, onNotification, onReconnect) {
|
|
106
|
-
assert(this.opened, 'Database not opened. Call
|
|
117
|
+
assert(this.opened, 'Database not opened. Call start() before using pg-boss, or again after stop().');
|
|
107
118
|
let closed = false;
|
|
108
119
|
let client = null;
|
|
109
120
|
let reconnectTimer = null;
|
|
@@ -245,7 +256,7 @@ class Db extends EventEmitter {
|
|
|
245
256
|
// to the next caller mid-transaction: a failed COMMIT, a connection that errors while checked
|
|
246
257
|
// out, and a ROLLBACK that cannot get through.
|
|
247
258
|
async beginTransaction() {
|
|
248
|
-
assert(this.opened, 'Database not opened. Call
|
|
259
|
+
assert(this.opened, 'Database not opened. Call start() before using pg-boss, or again after stop().');
|
|
249
260
|
const client = await this.pool.connect();
|
|
250
261
|
let released = false;
|
|
251
262
|
// Why the connection died, when it died on its own rather than through commit() or rollback().
|
package/dist/index.d.ts
CHANGED
|
@@ -6,6 +6,7 @@ export { QUEUE_POLICIES as policies } from './plans.ts';
|
|
|
6
6
|
export { SCHEDULE_KINDS as scheduleKinds } from './plans.ts';
|
|
7
7
|
export { SCHEDULE_MISSED_POLICIES as scheduleMissedPolicies } from './plans.ts';
|
|
8
8
|
export { PREVIEW_MAX_COUNT as previewScheduleMaxCount } from './timekeeper.ts';
|
|
9
|
+
export { addBins, percentile } from './latency.ts';
|
|
9
10
|
export declare const events: types.Events;
|
|
10
11
|
export declare function getConstructionPlans(schema?: string, options?: types.ConstructionPlanOptions): string;
|
|
11
12
|
export declare function getMigrationPlans(schema?: string, version?: number, options?: types.MigrationPlanOptions): string;
|
|
@@ -16,11 +17,17 @@ export declare function getMigrationPlans(schema?: string, version?: number, opt
|
|
|
16
17
|
*/
|
|
17
18
|
export declare function getIndexBloatPlans(schema?: string, options?: types.IndexBloatOptions): string;
|
|
18
19
|
export declare function getRollbackPlans(schema?: string, version?: number, options?: types.PlanOptions): string;
|
|
20
|
+
/**
|
|
21
|
+
* The SQL that removes every object pg-boss installs, for a schema it shares with other objects. A
|
|
22
|
+
* schema of pg-boss's own is simpler to drop whole.
|
|
23
|
+
* @see https://pgboss.io/api/utils#getuninstallplans-schema-options
|
|
24
|
+
*/
|
|
25
|
+
export declare function getUninstallPlans(schema?: string, options?: types.PlanOptions): string;
|
|
19
26
|
export declare class PgBoss extends EventEmitter<types.PgBossEventMap> {
|
|
20
27
|
#private;
|
|
21
28
|
constructor(connectionString: string);
|
|
22
29
|
constructor(options: types.ConstructorOptions);
|
|
23
|
-
start(): Promise<this>;
|
|
30
|
+
start(options?: types.StartOptions): Promise<this>;
|
|
24
31
|
stop(options?: types.StopOptions): Promise<void>;
|
|
25
32
|
send(request: types.Request): Promise<string | null>;
|
|
26
33
|
send(name: string, data?: object | null, options?: types.SendOptions): Promise<string | null>;
|
|
@@ -72,6 +79,7 @@ export declare class PgBoss extends EventEmitter<types.PgBossEventMap> {
|
|
|
72
79
|
getQueues(names?: string[]): Promise<types.QueueResult[]>;
|
|
73
80
|
getQueue(name: string): Promise<types.QueueResult | null>;
|
|
74
81
|
getQueueStats(name: string, options?: types.QueueStatsOptions): Promise<types.QueueStats[]>;
|
|
82
|
+
getInstances(): Promise<types.Instance[]>;
|
|
75
83
|
isMaintaining(): boolean;
|
|
76
84
|
isBamWorking(): boolean;
|
|
77
85
|
isResolvingFlow(): boolean;
|
|
@@ -103,7 +111,7 @@ export declare class PgBoss extends EventEmitter<types.PgBossEventMap> {
|
|
|
103
111
|
* such as `FREQ=MONTHLY;BYDAY=-1FR;BYHOUR=17`.
|
|
104
112
|
*/
|
|
105
113
|
schedule(name: string, cron: string, data?: object | null, options?: types.ScheduleOptions): Promise<void>;
|
|
106
|
-
unschedule(name: string, key?: string): Promise<void>;
|
|
114
|
+
unschedule(name: string, key?: string, options?: types.ConnectionOptions): Promise<void>;
|
|
107
115
|
getSchedules(name?: string, key?: string): Promise<types.Schedule[]>;
|
|
108
116
|
getSchedule(name: string, key?: string): Promise<types.Schedule | null>;
|
|
109
117
|
previewSchedule(cron: string, options?: types.PreviewScheduleOptions): Date[];
|
|
@@ -113,7 +121,7 @@ export declare class PgBoss extends EventEmitter<types.PgBossEventMap> {
|
|
|
113
121
|
}
|
|
114
122
|
export { systemClock, TestClock } from './clock.ts';
|
|
115
123
|
export { CLOCK_OVERRIDE_SETTING, enableClockOverride, disableClockOverride } from './plans.ts';
|
|
116
|
-
export type { BackendProfile, BackendOptions, AttachableClock, Clock, ClockTimer, BamEntry, BamEvent, BamStatusSummary, CommandResponse, CompleteOptions, ConnectionOptions, ConstructorOptions, DatabaseOptions, FetchGroupConcurrencyOptions, DependencyRef, FetchOptions, FindJobsOptions, FlowJob, GroupConcurrencyConfig, GroupOptions, IDatabase as Db, InsertOptions, IndexBloat, IndexBloatOptions, InvalidIndex, Job, JobAttempt, JobFetchOptions, JobInsert, JobMatchStrategy, JobOptions, JobPollingOptions, JobResult, JobResultStatus, JobStates, Events, JobWithMetadata, MaintenanceOptions, ManagedIndex, MigrationPartition, AsyncMigrationCommand, MismatchedIndex, ManagedFunction, MismatchedFunction, TableColumnDrift, ConstraintDrift, EnumDrift, OffWorkOptions, PgBossEventMap, PreviewScheduleOptions, Queue, QueueOptions, QueuePolicy, QueueResult, QueueStats, QueueStatsOptions, RedriveFilter, RedriveOptions, RedrivePreview, ReindexOptions, Request, Schedule, ScheduleKind, ScheduleOptions, SchedulingOptions, SchemaDriftReport, SendOptions, StopOptions, SuperviseOptions, UpdateOptions, UpdateQueueOptions, UpdateRequest, UpdateResponse, UpsertResponse, Warning, WipData, WorkConcurrencyOptions, WorkerState, WorkHandler, WorkOptions, WorkWithMetadataHandler, WorkHandlerFor, PerJobWorkHandler, PerJobWorkWithMetadataHandler, } from './types.ts';
|
|
124
|
+
export type { BackendProfile, BackendOptions, AttachableClock, Clock, ClockTimer, BamEntry, BamEvent, BamStatusSummary, CommandResponse, CompleteOptions, ConnectionOptions, ConstructorOptions, DatabaseOptions, FetchGroupConcurrencyOptions, DependencyRef, FetchOptions, FindJobsOptions, FlowJob, GroupConcurrencyConfig, GroupOptions, IDatabase as Db, InsertOptions, IndexBloat, IndexBloatOptions, InvalidIndex, Job, JobAttempt, JobFetchOptions, JobInsert, JobMatchStrategy, JobOptions, JobPollingOptions, JobResult, JobResultStatus, JobStates, Events, JobWithMetadata, MaintenanceOptions, ManagedIndex, MigrationPartition, AsyncMigrationCommand, MismatchedIndex, ManagedFunction, MismatchedFunction, TableColumnDrift, ConstraintDrift, EnumDrift, OffWorkOptions, OpenTelemetryOptions, PgBossEventMap, PreviewScheduleOptions, Queue, QueueOptions, QueuePolicy, QueueResult, QueueStats, QueueStatsPercentile, Instance, InstanceMetrics, InstanceOptions, InstanceWorker, PoolCounts, QueueStatsOptions, RedriveFilter, RedriveOptions, RedrivePreview, ReindexOptions, Request, Schedule, ScheduleKind, ScheduleOptions, SchedulingOptions, SchemaDriftReport, SendOptions, StopOptions, SuperviseOptions, UpdateOptions, UpdateQueueOptions, UpdateRequest, UpdateResponse, UpsertResponse, Warning, WipData, WorkConcurrencyOptions, WorkerState, WorkHandler, WorkOptions, WorkWithMetadataHandler, WorkHandlerFor, PerJobWorkHandler, PerJobWorkWithMetadataHandler, } from './types.ts';
|
|
117
125
|
export type { JobSpyInterface, JobSpyState, JobDataSelector, JobSelector, SpyJob, } from './spy.ts';
|
|
118
126
|
export { fromKnex, fromKysely, fromDrizzle, fromPrisma, fromPglite, fromBunSql, } from './adapters/index.ts';
|
|
119
127
|
export type { KnexTransactionLike, KyselyTransactionLike, DrizzleTransactionLike, DrizzleSqlTagLike, PrismaTransactionLike, PGliteLike, BunSqlLike, BunReservedSqlLike, } from './adapters/index.ts';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import assert from 'node:assert';
|
|
1
|
+
import assert, { AssertionError } from 'node:assert';
|
|
2
|
+
import { randomUUID } from 'node:crypto';
|
|
2
3
|
import EventEmitter from 'node:events';
|
|
3
4
|
import * as Attorney from "./attorney.js";
|
|
4
5
|
import Contractor from "./contractor.js";
|
|
@@ -8,6 +9,7 @@ import Boss from "./boss.js";
|
|
|
8
9
|
import Bam from "./bam.js";
|
|
9
10
|
import Navigator from "./navigator.js";
|
|
10
11
|
import Notifier from "./notifier.js";
|
|
12
|
+
import Registrar from "./registrar.js";
|
|
11
13
|
import { delay } from "./tools.js";
|
|
12
14
|
import { isAttachable } from "./clock.js";
|
|
13
15
|
import { trackActivity } from "./activity.js";
|
|
@@ -18,6 +20,7 @@ export { QUEUE_POLICIES as policies } from "./plans.js";
|
|
|
18
20
|
export { SCHEDULE_KINDS as scheduleKinds } from "./plans.js";
|
|
19
21
|
export { SCHEDULE_MISSED_POLICIES as scheduleMissedPolicies } from "./plans.js";
|
|
20
22
|
export { PREVIEW_MAX_COUNT as previewScheduleMaxCount } from "./timekeeper.js";
|
|
23
|
+
export { addBins, percentile } from "./latency.js";
|
|
21
24
|
export const events = Object.freeze({
|
|
22
25
|
error: 'error',
|
|
23
26
|
warning: 'warning',
|
|
@@ -43,10 +46,22 @@ export function getIndexBloatPlans(schema, options) {
|
|
|
43
46
|
export function getRollbackPlans(schema, version, options) {
|
|
44
47
|
return Contractor.rollbackPlans(schema, version, options);
|
|
45
48
|
}
|
|
49
|
+
/**
|
|
50
|
+
* The SQL that removes every object pg-boss installs, for a schema it shares with other objects. A
|
|
51
|
+
* schema of pg-boss's own is simpler to drop whole.
|
|
52
|
+
* @see https://pgboss.io/api/utils#getuninstallplans-schema-options
|
|
53
|
+
*/
|
|
54
|
+
export function getUninstallPlans(schema, options) {
|
|
55
|
+
return Contractor.uninstallPlans(schema, options);
|
|
56
|
+
}
|
|
57
|
+
// start({ attempts }) waits 1 second after the first failure and doubles the wait up to this.
|
|
58
|
+
const START_RETRY_MAX_SECONDS = 30;
|
|
46
59
|
export class PgBoss extends EventEmitter {
|
|
47
60
|
#stopped;
|
|
48
61
|
#started;
|
|
49
62
|
#startingPromise = null;
|
|
63
|
+
// The wait between start() attempts, so stop() can end it rather than sit out every retry.
|
|
64
|
+
#startRetry = null;
|
|
50
65
|
#stoppingPromise = null;
|
|
51
66
|
#attachedClock = null;
|
|
52
67
|
#idle;
|
|
@@ -59,11 +74,19 @@ export class PgBoss extends EventEmitter {
|
|
|
59
74
|
#bam;
|
|
60
75
|
#navigator;
|
|
61
76
|
#notifier;
|
|
77
|
+
#registrar;
|
|
62
78
|
constructor(value) {
|
|
63
79
|
super();
|
|
64
80
|
this.#stopped = true;
|
|
65
81
|
const config = Attorney.getConfig(value);
|
|
66
82
|
this.#config = config;
|
|
83
|
+
// Made here rather than at start(), since the pool is configured before it opens. Naming the
|
|
84
|
+
// connections after the instance is what lets pg_stat_activity join to its registry row. Only
|
|
85
|
+
// on a pool pg-boss creates, and never over a name the caller chose.
|
|
86
|
+
const instanceId = randomUUID();
|
|
87
|
+
if (config.registerInstance && !config.db && !config.application_name) {
|
|
88
|
+
config.application_name = `pgboss:${instanceId.slice(0, 8)}`;
|
|
89
|
+
}
|
|
67
90
|
let db = this.getDb();
|
|
68
91
|
// Before any component takes the db, so every statement they run is counted.
|
|
69
92
|
if (isAttachable(config.clock)) {
|
|
@@ -84,12 +107,14 @@ export class PgBoss extends EventEmitter {
|
|
|
84
107
|
const navigator = new Navigator(db, manager, config);
|
|
85
108
|
const notifier = new Notifier(db, manager, config);
|
|
86
109
|
manager.notifier = notifier;
|
|
110
|
+
const registrar = new Registrar(instanceId, db, manager, config);
|
|
87
111
|
this.#promoteEvents(manager);
|
|
88
112
|
this.#promoteEvents(boss);
|
|
89
113
|
this.#promoteEvents(timekeeper);
|
|
90
114
|
this.#promoteEvents(bam);
|
|
91
115
|
this.#promoteEvents(navigator);
|
|
92
116
|
this.#promoteEvents(notifier);
|
|
117
|
+
this.#promoteEvents(registrar);
|
|
93
118
|
this.#boss = boss;
|
|
94
119
|
this.#contractor = contractor;
|
|
95
120
|
this.#manager = manager;
|
|
@@ -97,13 +122,16 @@ export class PgBoss extends EventEmitter {
|
|
|
97
122
|
this.#bam = bam;
|
|
98
123
|
this.#navigator = navigator;
|
|
99
124
|
this.#notifier = notifier;
|
|
125
|
+
this.#registrar = registrar;
|
|
100
126
|
}
|
|
101
127
|
#promoteEvents(emitter) {
|
|
102
128
|
for (const event of Object.values(emitter?.events)) {
|
|
103
129
|
emitter.on(event, arg => this.emit(event, arg));
|
|
104
130
|
}
|
|
105
131
|
}
|
|
106
|
-
async start() {
|
|
132
|
+
async start(options = {}) {
|
|
133
|
+
const { attempts = 1 } = options;
|
|
134
|
+
assert(Number.isInteger(attempts) && attempts >= 1, 'start() attempts must be an integer of 1 or more');
|
|
107
135
|
// A stop() already in flight must finish (clearing any resources it's tearing down) before a
|
|
108
136
|
// fresh start() begins, otherwise the two race over the same intervals/pool.
|
|
109
137
|
if (this.#stoppingPromise) {
|
|
@@ -122,7 +150,7 @@ export class PgBoss extends EventEmitter {
|
|
|
122
150
|
// partway through, subsystems already started (e.g. manager's queueCacheInterval/wipInterval)
|
|
123
151
|
// must still be reachable by stop() for cleanup, and stop() no-ops whenever #stopped is true.
|
|
124
152
|
this.#stopped = false;
|
|
125
|
-
this.#startingPromise = this.#
|
|
153
|
+
this.#startingPromise = this.#startAttempts(attempts);
|
|
126
154
|
try {
|
|
127
155
|
return await this.#startingPromise;
|
|
128
156
|
}
|
|
@@ -130,7 +158,44 @@ export class PgBoss extends EventEmitter {
|
|
|
130
158
|
this.#startingPromise = null;
|
|
131
159
|
}
|
|
132
160
|
}
|
|
133
|
-
|
|
161
|
+
// Each attempt is the same as calling start() again after a failure, which is safe on the same
|
|
162
|
+
// instance. An AssertionError is pg-boss refusing a configuration it cannot run, which fails the
|
|
163
|
+
// same way every time, so it is thrown at once. Anything else, a database not up yet or a schema
|
|
164
|
+
// another process is still migrating, gets the remaining attempts.
|
|
165
|
+
async #startAttempts(attempts) {
|
|
166
|
+
const retry = { cancelled: false, wait: null };
|
|
167
|
+
this.#startRetry = retry;
|
|
168
|
+
try {
|
|
169
|
+
for (let attempt = 1;; attempt++) {
|
|
170
|
+
try {
|
|
171
|
+
return await this.#doStart(attempt);
|
|
172
|
+
}
|
|
173
|
+
catch (err) {
|
|
174
|
+
if (attempt >= attempts || retry.cancelled || err instanceof AssertionError) {
|
|
175
|
+
throw err;
|
|
176
|
+
}
|
|
177
|
+
const delaySeconds = Math.min(2 ** (attempt - 1), START_RETRY_MAX_SECONDS);
|
|
178
|
+
// Once per start(), on the first failure: an outage would otherwise repeat it every try.
|
|
179
|
+
if (attempt === 1) {
|
|
180
|
+
this.emit(events.warning, {
|
|
181
|
+
message: `start() failed and will try again, up to ${attempts - 1} more times: ${err?.message}`,
|
|
182
|
+
data: { type: 'start_retry', attempts, error: err?.message }
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
retry.wait = delay(delaySeconds * 1000);
|
|
186
|
+
await retry.wait;
|
|
187
|
+
retry.wait = null;
|
|
188
|
+
if (retry.cancelled) {
|
|
189
|
+
throw err;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
finally {
|
|
195
|
+
this.#startRetry = null;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
async #doStart(attempt = 1) {
|
|
134
199
|
// Before anything opens a connection or runs a statement. The schema clock is gated on a
|
|
135
200
|
// session setting, and a session that misses it reads real time while its peers read fake
|
|
136
201
|
// time - silently, and differently on every checkout. Declaring the setup here means no
|
|
@@ -165,6 +230,7 @@ export class PgBoss extends EventEmitter {
|
|
|
165
230
|
if (this.#config.migrate) {
|
|
166
231
|
await this.#bam.start();
|
|
167
232
|
}
|
|
233
|
+
await this.#registrar.start(attempt);
|
|
168
234
|
this.#started = true;
|
|
169
235
|
return this;
|
|
170
236
|
}
|
|
@@ -179,7 +245,7 @@ export class PgBoss extends EventEmitter {
|
|
|
179
245
|
if (/yugabyte|-yb-/i.test(version)) {
|
|
180
246
|
if (!this.#config.noTablePartitioning || !this.#config.noAdvisoryLocks) {
|
|
181
247
|
this.emit(events.warning, {
|
|
182
|
-
message: "YugabyteDB detected
|
|
248
|
+
message: "YugabyteDB detected. YugabyteDB is not supported. Until the next major, backend: 'yugabytedb' avoids the table partitioning and advisory locks that fail there.",
|
|
183
249
|
data: { backend: 'yugabytedb' }
|
|
184
250
|
});
|
|
185
251
|
}
|
|
@@ -191,7 +257,12 @@ export class PgBoss extends EventEmitter {
|
|
|
191
257
|
}
|
|
192
258
|
async stop(options = {}) {
|
|
193
259
|
// A start() already in flight must finish (or fail) before stop() evaluates state, otherwise
|
|
194
|
-
// stop() reads #stopped mid-start and silently no-ops while start() keeps running.
|
|
260
|
+
// stop() reads #stopped mid-start and silently no-ops while start() keeps running. One waiting
|
|
261
|
+
// between attempts stops trying, so it fails now with its last error.
|
|
262
|
+
if (this.#startRetry) {
|
|
263
|
+
this.#startRetry.cancelled = true;
|
|
264
|
+
this.#startRetry.wait?.abort();
|
|
265
|
+
}
|
|
195
266
|
if (this.#startingPromise) {
|
|
196
267
|
await this.#startingPromise.catch(() => { });
|
|
197
268
|
}
|
|
@@ -233,6 +304,11 @@ export class PgBoss extends EventEmitter {
|
|
|
233
304
|
await this.#bam.stop();
|
|
234
305
|
const shutdown = async () => {
|
|
235
306
|
await this.#manager.failWip();
|
|
307
|
+
// Pending claims may not have reached worker.jobs when failWip ran. Drain their refusal
|
|
308
|
+
// before closing the pool or publishing stopped.
|
|
309
|
+
await this.#manager.settleCleanups();
|
|
310
|
+
// After the drain, so a graceful stop reads as live until its workers have finished.
|
|
311
|
+
await this.#registrar.stop();
|
|
236
312
|
const attachment = this.#attachedClock;
|
|
237
313
|
this.#attachedClock = null;
|
|
238
314
|
try {
|
|
@@ -261,7 +337,7 @@ export class PgBoss extends EventEmitter {
|
|
|
261
337
|
await shutdown();
|
|
262
338
|
return;
|
|
263
339
|
}
|
|
264
|
-
// Real time, not the configured clock: the deadline bounds
|
|
340
|
+
// Real time, not the configured clock: the deadline bounds active-handler grace, and under a test
|
|
265
341
|
// clock nothing would tick it while the test is blocked inside stop().
|
|
266
342
|
let deadlineTimer;
|
|
267
343
|
const deadline = new Promise(resolve => { deadlineTimer = setTimeout(resolve, timeout); });
|
|
@@ -398,6 +474,9 @@ export class PgBoss extends EventEmitter {
|
|
|
398
474
|
getQueueStats(name, options) {
|
|
399
475
|
return this.#manager.getQueueStats(name, options);
|
|
400
476
|
}
|
|
477
|
+
getInstances() {
|
|
478
|
+
return this.#registrar.getInstances();
|
|
479
|
+
}
|
|
401
480
|
isMaintaining() {
|
|
402
481
|
return this.#boss.maintaining;
|
|
403
482
|
}
|
|
@@ -459,8 +538,8 @@ export class PgBoss extends EventEmitter {
|
|
|
459
538
|
schedule(name, cron, data, options) {
|
|
460
539
|
return this.#timekeeper.schedule(name, cron, data, options);
|
|
461
540
|
}
|
|
462
|
-
unschedule(name, key) {
|
|
463
|
-
return this.#timekeeper.unschedule(name, key);
|
|
541
|
+
unschedule(name, key, options) {
|
|
542
|
+
return this.#timekeeper.unschedule(name, key, options);
|
|
464
543
|
}
|
|
465
544
|
getSchedules(name, key) {
|
|
466
545
|
return this.#timekeeper.getSchedules(name, key);
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
type Bins = number[] | null | undefined;
|
|
2
|
+
/**
|
|
3
|
+
* Combines two wait or run histograms into one by adding their counts bin by bin, as if all their
|
|
4
|
+
* jobs had been recorded together. A null histogram counts as empty; null only when both are.
|
|
5
|
+
* @see https://pgboss.io/api/utils#addbins-a-b
|
|
6
|
+
*/
|
|
7
|
+
export declare function addBins(a: Bins, b: Bins): number[] | null;
|
|
8
|
+
/**
|
|
9
|
+
* The time in seconds below which `p` percent (1 to 100) of a wait or run histogram's jobs fall,
|
|
10
|
+
* estimated within its bin, so `percentile(bins, 95)` is the p95. Null for an empty histogram.
|
|
11
|
+
* @see https://pgboss.io/api/utils#percentile-bins-p
|
|
12
|
+
*/
|
|
13
|
+
export declare function percentile(bins: Bins, p: number): number | null;
|
|
14
|
+
export {};
|
|
15
|
+
//# sourceMappingURL=latency.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"latency.d.ts","sourceRoot":"","sources":["../src/latency.ts"],"names":[],"mappings":"AAGA,KAAK,IAAI,GAAG,MAAM,EAAE,GAAG,IAAI,GAAG,SAAS,CAAA;AAMvC;;;;GAIG;AACH,wBAAgB,OAAO,CAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,GAAG,MAAM,EAAE,GAAG,IAAI,CAI1D;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAE,IAAI,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAoBhE"}
|