@dbos-inc/dbos-enterprise 5.4.1-preview → 5.4.2-preview
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 +0 -2
- package/dist/src/auto_upgrade.d.ts +7 -20
- package/dist/src/auto_upgrade.d.ts.map +1 -1
- package/dist/src/auto_upgrade.js +7 -51
- package/dist/src/auto_upgrade.js.map +1 -1
- package/dist/src/cockroach.d.ts +7 -1
- package/dist/src/cockroach.d.ts.map +1 -1
- package/dist/src/cockroach.js +7 -1
- package/dist/src/cockroach.js.map +1 -1
- package/dist/src/conductor/conductor.d.ts +8 -5
- package/dist/src/conductor/conductor.d.ts.map +1 -1
- package/dist/src/conductor/conductor.js +765 -735
- package/dist/src/conductor/conductor.js.map +1 -1
- package/dist/src/conductor/protocol.d.ts +31 -7
- package/dist/src/conductor/protocol.d.ts.map +1 -1
- package/dist/src/conductor/protocol.js +84 -17
- package/dist/src/conductor/protocol.js.map +1 -1
- package/dist/src/export.d.ts +7 -0
- package/dist/src/export.d.ts.map +1 -1
- package/dist/src/export.js +15 -21
- package/dist/src/export.js.map +1 -1
- package/dist/src/fork.d.ts +7 -0
- package/dist/src/fork.d.ts.map +1 -1
- package/dist/src/fork.js +11 -3
- package/dist/src/fork.js.map +1 -1
- package/dist/src/index.d.ts +8 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +10 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/locks.d.ts +20 -0
- package/dist/src/locks.d.ts.map +1 -0
- package/dist/src/locks.js +47 -0
- package/dist/src/locks.js.map +1 -0
- package/dist/src/observability.d.ts +8 -0
- package/dist/src/observability.d.ts.map +1 -1
- package/dist/src/observability.js +63 -43
- package/dist/src/observability.js.map +1 -1
- package/dist/src/retention.d.ts +16 -34
- package/dist/src/retention.d.ts.map +1 -1
- package/dist/src/retention.js +148 -176
- package/dist/src/retention.js.map +1 -1
- package/dist/src/sharding/index.d.ts +9 -0
- package/dist/src/sharding/index.d.ts.map +1 -0
- package/dist/src/sharding/index.js +13 -0
- package/dist/src/sharding/index.js.map +1 -0
- package/dist/src/sharding/migrations.d.ts +20 -0
- package/dist/src/sharding/migrations.d.ts.map +1 -0
- package/dist/src/sharding/migrations.js +486 -0
- package/dist/src/sharding/migrations.js.map +1 -0
- package/dist/src/sharding/schema.d.ts +9 -0
- package/dist/src/sharding/schema.d.ts.map +1 -0
- package/dist/src/sharding/schema.js +12 -0
- package/dist/src/sharding/schema.js.map +1 -0
- package/dist/src/sharding/sys_db.d.ts +101 -0
- package/dist/src/sharding/sys_db.d.ts.map +1 -0
- package/dist/src/sharding/sys_db.js +717 -0
- package/dist/src/sharding/sys_db.js.map +1 -0
- package/package.json +3 -3
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
// Copyright (c) 2026 DBOS, Inc. All rights reserved.
|
|
2
|
+
//
|
|
3
|
+
// This file is part of Transact Enterprise, proprietary software licensed under the
|
|
4
|
+
// DBOS Conductor Software License: https://www.dbos.dev/conductor-license
|
|
5
|
+
// You may not use, copy, modify, or distribute this file except as that license permits.
|
|
6
|
+
// Disabling or circumventing the entitlement checks in @dbos-inc/dbos-sdk's src/enterprise.ts
|
|
7
|
+
// that gate it is a material breach of that license.
|
|
8
|
+
import type { PoolClient } from 'pg';
|
|
9
|
+
import { type SystemDatabase } from '@dbos-inc/dbos-sdk/internal/system_database';
|
|
10
|
+
export interface Statement {
|
|
11
|
+
sql: string;
|
|
12
|
+
creates?: string;
|
|
13
|
+
}
|
|
14
|
+
export declare function getShardedMigrations(schema: string): Statement[][];
|
|
15
|
+
export declare const LATEST_VERSION: number;
|
|
16
|
+
export declare function currentVersion(sysdb: SystemDatabase): Promise<number>;
|
|
17
|
+
export declare function citusInstalled(client: PoolClient): Promise<boolean>;
|
|
18
|
+
export declare function runMigrations(sysdb: SystemDatabase): Promise<void>;
|
|
19
|
+
export declare function verifyMigrations(sysdb: SystemDatabase): Promise<void>;
|
|
20
|
+
//# sourceMappingURL=migrations.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migrations.d.ts","sourceRoot":"","sources":["../../../src/sharding/migrations.ts"],"names":[],"mappings":";;;;;;;AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAErC,OAAO,EAAqB,KAAK,cAAc,EAAE,MAAM,6CAA6C,CAAC;AAQrG,MAAM,WAAW,SAAS;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAkXD,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,EAAE,EAAE,CAGlE;AAED,eAAO,MAAM,cAAc,QAAsC,CAAC;AAOlE,wBAAsB,cAAc,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAO3E;AA0BD,wBAAsB,cAAc,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,CAGzE;AAoBD,wBAAsB,aAAa,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAgCxE;AA4BD,wBAAsB,gBAAgB,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAU3E"}
|
|
@@ -0,0 +1,486 @@
|
|
|
1
|
+
// Copyright (c) 2026 DBOS, Inc. All rights reserved.
|
|
2
|
+
//
|
|
3
|
+
// This file is part of Transact Enterprise, proprietary software licensed under the
|
|
4
|
+
// DBOS Conductor Software License: https://www.dbos.dev/conductor-license
|
|
5
|
+
// You may not use, copy, modify, or distribute this file except as that license permits.
|
|
6
|
+
// Disabling or circumventing the entitlement checks in @dbos-inc/dbos-sdk's src/enterprise.ts
|
|
7
|
+
// that gate it is a material breach of that license.
|
|
8
|
+
"use strict";
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.verifyMigrations = exports.runMigrations = exports.citusInstalled = exports.currentVersion = exports.LATEST_VERSION = exports.getShardedMigrations = void 0;
|
|
11
|
+
const error_1 = require("@dbos-inc/dbos-sdk/internal/error");
|
|
12
|
+
const system_database_1 = require("@dbos-inc/dbos-sdk/internal/system_database");
|
|
13
|
+
const utils_1 = require("@dbos-inc/dbos-sdk/internal/utils");
|
|
14
|
+
const locks_1 = require("../locks");
|
|
15
|
+
const schema_1 = require("./schema");
|
|
16
|
+
const MIGRATION_LOCK_TIMEOUT_MS = 30_000;
|
|
17
|
+
function migrationOne(s) {
|
|
18
|
+
return [
|
|
19
|
+
{ sql: `CREATE SCHEMA IF NOT EXISTS ${s}` },
|
|
20
|
+
{
|
|
21
|
+
sql: `CREATE TABLE IF NOT EXISTS ${s}.dbos_migrations (
|
|
22
|
+
shard_key text NOT NULL,
|
|
23
|
+
version bigint NOT NULL,
|
|
24
|
+
PRIMARY KEY (shard_key)
|
|
25
|
+
)`,
|
|
26
|
+
creates: 'dbos_migrations',
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
sql: `CREATE TABLE IF NOT EXISTS ${s}.workflow_status (
|
|
30
|
+
shard_key text NOT NULL,
|
|
31
|
+
workflow_uuid text NOT NULL,
|
|
32
|
+
status text,
|
|
33
|
+
name text,
|
|
34
|
+
authenticated_user text,
|
|
35
|
+
assumed_role text,
|
|
36
|
+
authenticated_roles text,
|
|
37
|
+
request text,
|
|
38
|
+
output text,
|
|
39
|
+
error text,
|
|
40
|
+
executor_id text,
|
|
41
|
+
created_at bigint DEFAULT ((EXTRACT(epoch FROM now()) * 1000.0))::bigint NOT NULL,
|
|
42
|
+
updated_at bigint DEFAULT ((EXTRACT(epoch FROM now()) * 1000.0))::bigint NOT NULL,
|
|
43
|
+
application_version text,
|
|
44
|
+
application_id text,
|
|
45
|
+
class_name character varying(255) DEFAULT NULL,
|
|
46
|
+
config_name character varying(255) DEFAULT NULL,
|
|
47
|
+
recovery_attempts bigint DEFAULT 0,
|
|
48
|
+
queue_name text,
|
|
49
|
+
workflow_timeout_ms bigint,
|
|
50
|
+
workflow_deadline_epoch_ms bigint,
|
|
51
|
+
inputs text,
|
|
52
|
+
started_at_epoch_ms bigint,
|
|
53
|
+
deduplication_id text,
|
|
54
|
+
priority int4 DEFAULT 0 NOT NULL,
|
|
55
|
+
queue_partition_key text,
|
|
56
|
+
forked_from text,
|
|
57
|
+
owner_xid text,
|
|
58
|
+
parent_workflow_id text,
|
|
59
|
+
parent_shard_key text,
|
|
60
|
+
serialization text,
|
|
61
|
+
delay_until_epoch_ms bigint,
|
|
62
|
+
was_forked_from boolean DEFAULT false NOT NULL,
|
|
63
|
+
rate_limited boolean DEFAULT false NOT NULL,
|
|
64
|
+
completed_at bigint,
|
|
65
|
+
attributes jsonb,
|
|
66
|
+
schedule_name text,
|
|
67
|
+
debounce_deadline_epoch_ms bigint,
|
|
68
|
+
is_debounced boolean DEFAULT false NOT NULL,
|
|
69
|
+
application_name text,
|
|
70
|
+
creator_xid text,
|
|
71
|
+
PRIMARY KEY (shard_key, workflow_uuid)
|
|
72
|
+
)`,
|
|
73
|
+
creates: 'workflow_status',
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
sql: `CREATE TABLE IF NOT EXISTS ${s}.workflow_input (
|
|
77
|
+
shard_key text NOT NULL,
|
|
78
|
+
workflow_uuid text NOT NULL,
|
|
79
|
+
inputs text,
|
|
80
|
+
retention_timestamp bigint DEFAULT ((EXTRACT(epoch FROM now()) * 1000.0))::bigint NOT NULL,
|
|
81
|
+
PRIMARY KEY (shard_key, workflow_uuid)
|
|
82
|
+
)`,
|
|
83
|
+
creates: 'workflow_input',
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
sql: `CREATE TABLE IF NOT EXISTS ${s}.workflow_output (
|
|
87
|
+
shard_key text NOT NULL,
|
|
88
|
+
workflow_uuid text NOT NULL,
|
|
89
|
+
output text,
|
|
90
|
+
error text,
|
|
91
|
+
retention_timestamp bigint DEFAULT ((EXTRACT(epoch FROM now()) * 1000.0))::bigint NOT NULL,
|
|
92
|
+
PRIMARY KEY (shard_key, workflow_uuid)
|
|
93
|
+
)`,
|
|
94
|
+
creates: 'workflow_output',
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
sql: `CREATE TABLE IF NOT EXISTS ${s}.operation_outputs (
|
|
98
|
+
shard_key text NOT NULL,
|
|
99
|
+
workflow_uuid text NOT NULL,
|
|
100
|
+
function_id int4 NOT NULL,
|
|
101
|
+
function_name text DEFAULT '' NOT NULL,
|
|
102
|
+
output text,
|
|
103
|
+
error text,
|
|
104
|
+
child_workflow_id text,
|
|
105
|
+
child_shard_key text,
|
|
106
|
+
started_at_epoch_ms bigint,
|
|
107
|
+
completed_at_epoch_ms bigint,
|
|
108
|
+
serialization text,
|
|
109
|
+
application_name text,
|
|
110
|
+
retention_timestamp bigint DEFAULT ((EXTRACT(epoch FROM now()) * 1000.0))::bigint NOT NULL,
|
|
111
|
+
PRIMARY KEY (shard_key, workflow_uuid, function_id)
|
|
112
|
+
)`,
|
|
113
|
+
creates: 'operation_outputs',
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
sql: `CREATE TABLE IF NOT EXISTS ${s}.notifications (
|
|
117
|
+
shard_key text NOT NULL,
|
|
118
|
+
message_uuid text DEFAULT gen_random_uuid() NOT NULL,
|
|
119
|
+
destination_uuid text NOT NULL,
|
|
120
|
+
topic text,
|
|
121
|
+
message text NOT NULL,
|
|
122
|
+
created_at_epoch_ms bigint DEFAULT ((EXTRACT(epoch FROM now()) * 1000.0))::bigint NOT NULL,
|
|
123
|
+
serialization text,
|
|
124
|
+
consumed boolean DEFAULT false NOT NULL,
|
|
125
|
+
consumed_by_function_id int4,
|
|
126
|
+
PRIMARY KEY (shard_key, message_uuid),
|
|
127
|
+
FOREIGN KEY (shard_key, destination_uuid)
|
|
128
|
+
REFERENCES ${s}.workflow_status (shard_key, workflow_uuid) ON DELETE CASCADE
|
|
129
|
+
)`,
|
|
130
|
+
creates: 'notifications',
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
sql: `CREATE TABLE IF NOT EXISTS ${s}.workflow_events (
|
|
134
|
+
shard_key text NOT NULL,
|
|
135
|
+
workflow_uuid text NOT NULL,
|
|
136
|
+
key text NOT NULL,
|
|
137
|
+
value text NOT NULL,
|
|
138
|
+
serialization text,
|
|
139
|
+
PRIMARY KEY (shard_key, workflow_uuid, key),
|
|
140
|
+
FOREIGN KEY (shard_key, workflow_uuid)
|
|
141
|
+
REFERENCES ${s}.workflow_status (shard_key, workflow_uuid) ON DELETE CASCADE
|
|
142
|
+
)`,
|
|
143
|
+
creates: 'workflow_events',
|
|
144
|
+
},
|
|
145
|
+
{
|
|
146
|
+
sql: `CREATE TABLE IF NOT EXISTS ${s}.workflow_events_history (
|
|
147
|
+
shard_key text NOT NULL,
|
|
148
|
+
workflow_uuid text NOT NULL,
|
|
149
|
+
function_id int4 NOT NULL,
|
|
150
|
+
key text NOT NULL,
|
|
151
|
+
value text NOT NULL,
|
|
152
|
+
serialization text,
|
|
153
|
+
PRIMARY KEY (shard_key, workflow_uuid, function_id, key),
|
|
154
|
+
FOREIGN KEY (shard_key, workflow_uuid)
|
|
155
|
+
REFERENCES ${s}.workflow_status (shard_key, workflow_uuid) ON DELETE CASCADE
|
|
156
|
+
)`,
|
|
157
|
+
creates: 'workflow_events_history',
|
|
158
|
+
},
|
|
159
|
+
{
|
|
160
|
+
sql: `CREATE TABLE IF NOT EXISTS ${s}.streams (
|
|
161
|
+
shard_key text NOT NULL,
|
|
162
|
+
workflow_uuid text NOT NULL,
|
|
163
|
+
key text NOT NULL,
|
|
164
|
+
value text NOT NULL,
|
|
165
|
+
"offset" int4 NOT NULL,
|
|
166
|
+
function_id int4 DEFAULT 0 NOT NULL,
|
|
167
|
+
serialization text,
|
|
168
|
+
PRIMARY KEY (shard_key, workflow_uuid, key, "offset"),
|
|
169
|
+
FOREIGN KEY (shard_key, workflow_uuid)
|
|
170
|
+
REFERENCES ${s}.workflow_status (shard_key, workflow_uuid) ON DELETE CASCADE
|
|
171
|
+
)`,
|
|
172
|
+
creates: 'streams',
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
sql: `CREATE TABLE IF NOT EXISTS ${s}.workflow_schedules (
|
|
176
|
+
shard_key text NOT NULL,
|
|
177
|
+
schedule_id text NOT NULL,
|
|
178
|
+
schedule_name text NOT NULL,
|
|
179
|
+
workflow_name text NOT NULL,
|
|
180
|
+
workflow_class_name text,
|
|
181
|
+
schedule text NOT NULL,
|
|
182
|
+
status text DEFAULT 'ACTIVE' NOT NULL,
|
|
183
|
+
context text NOT NULL,
|
|
184
|
+
last_fired_at text,
|
|
185
|
+
automatic_backfill boolean DEFAULT false NOT NULL,
|
|
186
|
+
cron_timezone text,
|
|
187
|
+
queue_name text,
|
|
188
|
+
application_name text,
|
|
189
|
+
workflow_shard_key text NOT NULL,
|
|
190
|
+
PRIMARY KEY (shard_key, schedule_id),
|
|
191
|
+
UNIQUE (shard_key, schedule_name)
|
|
192
|
+
)`,
|
|
193
|
+
creates: 'workflow_schedules',
|
|
194
|
+
},
|
|
195
|
+
{
|
|
196
|
+
sql: `CREATE TABLE IF NOT EXISTS ${s}.application_versions (
|
|
197
|
+
shard_key text NOT NULL,
|
|
198
|
+
version_id text NOT NULL,
|
|
199
|
+
version_name text NOT NULL,
|
|
200
|
+
version_timestamp bigint DEFAULT ((EXTRACT(epoch FROM now()) * 1000.0))::bigint NOT NULL,
|
|
201
|
+
created_at bigint DEFAULT ((EXTRACT(epoch FROM now()) * 1000.0))::bigint NOT NULL,
|
|
202
|
+
application_name text,
|
|
203
|
+
PRIMARY KEY (shard_key, version_id),
|
|
204
|
+
UNIQUE (shard_key, version_name)
|
|
205
|
+
)`,
|
|
206
|
+
creates: 'application_versions',
|
|
207
|
+
},
|
|
208
|
+
{
|
|
209
|
+
sql: `CREATE TABLE IF NOT EXISTS ${s}.queues (
|
|
210
|
+
shard_key text NOT NULL,
|
|
211
|
+
queue_id text DEFAULT (gen_random_uuid())::text NOT NULL,
|
|
212
|
+
name text NOT NULL,
|
|
213
|
+
concurrency int4,
|
|
214
|
+
worker_concurrency int4,
|
|
215
|
+
rate_limit_max int4,
|
|
216
|
+
rate_limit_period_sec double precision,
|
|
217
|
+
priority_enabled boolean DEFAULT false NOT NULL,
|
|
218
|
+
partition_queue boolean DEFAULT false NOT NULL,
|
|
219
|
+
polling_interval_sec double precision DEFAULT 1.0 NOT NULL,
|
|
220
|
+
created_at bigint DEFAULT ((EXTRACT(epoch FROM now()) * 1000.0))::bigint NOT NULL,
|
|
221
|
+
updated_at bigint DEFAULT ((EXTRACT(epoch FROM now()) * 1000.0))::bigint NOT NULL,
|
|
222
|
+
application_name text,
|
|
223
|
+
partition_concurrency int4,
|
|
224
|
+
partition_worker_concurrency int4,
|
|
225
|
+
partition_rate_limit_max int4,
|
|
226
|
+
partition_rate_limit_period_sec double precision,
|
|
227
|
+
PRIMARY KEY (shard_key, queue_id),
|
|
228
|
+
UNIQUE (shard_key, name)
|
|
229
|
+
)`,
|
|
230
|
+
creates: 'queues',
|
|
231
|
+
},
|
|
232
|
+
{
|
|
233
|
+
sql: `CREATE INDEX IF NOT EXISTS idx_workflow_status_in_flight_v2
|
|
234
|
+
ON ${s}.workflow_status (shard_key, queue_name, status, priority, created_at)
|
|
235
|
+
INCLUDE (application_name)
|
|
236
|
+
WHERE status IN ('ENQUEUED', 'PENDING')`,
|
|
237
|
+
},
|
|
238
|
+
{
|
|
239
|
+
sql: `CREATE INDEX IF NOT EXISTS idx_workflow_status_partition_dequeue_v3
|
|
240
|
+
ON ${s}.workflow_status (shard_key, queue_name, status, queue_partition_key, priority, created_at, workflow_uuid)
|
|
241
|
+
INCLUDE (application_name)
|
|
242
|
+
WHERE status IN ('ENQUEUED', 'PENDING') AND queue_partition_key IS NOT NULL`,
|
|
243
|
+
},
|
|
244
|
+
{
|
|
245
|
+
sql: `CREATE INDEX IF NOT EXISTS idx_workflow_status_rate_limited
|
|
246
|
+
ON ${s}.workflow_status (shard_key, queue_name, started_at_epoch_ms)
|
|
247
|
+
WHERE rate_limited = true`,
|
|
248
|
+
},
|
|
249
|
+
{
|
|
250
|
+
sql: `CREATE INDEX IF NOT EXISTS idx_workflow_status_keyed_created_at
|
|
251
|
+
ON ${s}.workflow_status (shard_key, created_at)`,
|
|
252
|
+
},
|
|
253
|
+
{
|
|
254
|
+
sql: `CREATE INDEX IF NOT EXISTS idx_workflow_status_queue_keys
|
|
255
|
+
ON ${s}.workflow_status (queue_name, status, shard_key)
|
|
256
|
+
INCLUDE (application_name)
|
|
257
|
+
WHERE status IN ('ENQUEUED', 'PENDING')`,
|
|
258
|
+
},
|
|
259
|
+
{
|
|
260
|
+
sql: `CREATE INDEX IF NOT EXISTS workflow_status_created_at_index
|
|
261
|
+
ON ${s}.workflow_status (created_at)`,
|
|
262
|
+
},
|
|
263
|
+
{
|
|
264
|
+
sql: `CREATE INDEX IF NOT EXISTS idx_workflow_status_pending
|
|
265
|
+
ON ${s}.workflow_status (created_at)
|
|
266
|
+
WHERE status = 'PENDING'`,
|
|
267
|
+
},
|
|
268
|
+
{
|
|
269
|
+
sql: `CREATE INDEX IF NOT EXISTS idx_workflow_status_failed
|
|
270
|
+
ON ${s}.workflow_status (status, created_at)
|
|
271
|
+
WHERE status IN ('ERROR', 'CANCELLED', 'MAX_RECOVERY_ATTEMPTS_EXCEEDED')`,
|
|
272
|
+
},
|
|
273
|
+
{
|
|
274
|
+
sql: `CREATE INDEX IF NOT EXISTS idx_workflow_status_delayed
|
|
275
|
+
ON ${s}.workflow_status (delay_until_epoch_ms)
|
|
276
|
+
WHERE status = 'DELAYED'`,
|
|
277
|
+
},
|
|
278
|
+
{
|
|
279
|
+
sql: `CREATE INDEX IF NOT EXISTS idx_workflow_status_deadline
|
|
280
|
+
ON ${s}.workflow_status (workflow_deadline_epoch_ms)
|
|
281
|
+
WHERE status IN ('ENQUEUED', 'PENDING', 'DELAYED') AND workflow_deadline_epoch_ms IS NOT NULL`,
|
|
282
|
+
},
|
|
283
|
+
{
|
|
284
|
+
sql: `CREATE INDEX IF NOT EXISTS idx_workflow_status_completed_at
|
|
285
|
+
ON ${s}.workflow_status (completed_at)
|
|
286
|
+
WHERE completed_at IS NOT NULL`,
|
|
287
|
+
},
|
|
288
|
+
{
|
|
289
|
+
sql: `CREATE INDEX IF NOT EXISTS idx_workflow_status_started_at
|
|
290
|
+
ON ${s}.workflow_status (started_at_epoch_ms)
|
|
291
|
+
WHERE started_at_epoch_ms IS NOT NULL`,
|
|
292
|
+
},
|
|
293
|
+
{
|
|
294
|
+
sql: `CREATE INDEX IF NOT EXISTS idx_workflow_status_parent_workflow_id
|
|
295
|
+
ON ${s}.workflow_status (parent_workflow_id)
|
|
296
|
+
WHERE parent_workflow_id IS NOT NULL`,
|
|
297
|
+
},
|
|
298
|
+
{
|
|
299
|
+
sql: `CREATE INDEX IF NOT EXISTS idx_workflow_status_forked_from
|
|
300
|
+
ON ${s}.workflow_status (forked_from)
|
|
301
|
+
WHERE forked_from IS NOT NULL`,
|
|
302
|
+
},
|
|
303
|
+
{
|
|
304
|
+
sql: `CREATE INDEX IF NOT EXISTS idx_workflow_status_schedule_name
|
|
305
|
+
ON ${s}.workflow_status (schedule_name)
|
|
306
|
+
WHERE schedule_name IS NOT NULL`,
|
|
307
|
+
},
|
|
308
|
+
{
|
|
309
|
+
sql: `CREATE INDEX IF NOT EXISTS idx_workflow_status_attributes
|
|
310
|
+
ON ${s}.workflow_status USING gin (attributes)
|
|
311
|
+
WHERE attributes IS NOT NULL`,
|
|
312
|
+
},
|
|
313
|
+
{
|
|
314
|
+
sql: `CREATE INDEX IF NOT EXISTS idx_workflow_input_retention
|
|
315
|
+
ON ${s}.workflow_input (retention_timestamp)`,
|
|
316
|
+
},
|
|
317
|
+
{
|
|
318
|
+
sql: `CREATE INDEX IF NOT EXISTS idx_workflow_output_retention
|
|
319
|
+
ON ${s}.workflow_output (retention_timestamp)`,
|
|
320
|
+
},
|
|
321
|
+
{
|
|
322
|
+
sql: `CREATE INDEX IF NOT EXISTS idx_operation_outputs_retention
|
|
323
|
+
ON ${s}.operation_outputs (retention_timestamp)`,
|
|
324
|
+
},
|
|
325
|
+
{
|
|
326
|
+
sql: `CREATE INDEX IF NOT EXISTS idx_operation_outputs_completed_at_function_name_v2
|
|
327
|
+
ON ${s}.operation_outputs (completed_at_epoch_ms, function_name)
|
|
328
|
+
INCLUDE (application_name)`,
|
|
329
|
+
},
|
|
330
|
+
{
|
|
331
|
+
sql: `CREATE INDEX IF NOT EXISTS idx_workflow_topic
|
|
332
|
+
ON ${s}.notifications (shard_key, destination_uuid, topic)`,
|
|
333
|
+
},
|
|
334
|
+
{
|
|
335
|
+
sql: `CREATE UNIQUE INDEX IF NOT EXISTS uq_application_versions_owner_version
|
|
336
|
+
ON ${s}.application_versions (shard_key, application_name, version_name)
|
|
337
|
+
WHERE application_name IS NOT NULL`,
|
|
338
|
+
},
|
|
339
|
+
{
|
|
340
|
+
sql: `CREATE UNIQUE INDEX IF NOT EXISTS uq_application_versions_unclaimed_version
|
|
341
|
+
ON ${s}.application_versions (shard_key, version_name)
|
|
342
|
+
WHERE application_name IS NULL`,
|
|
343
|
+
},
|
|
344
|
+
{
|
|
345
|
+
sql: `CREATE INDEX IF NOT EXISTS idx_application_versions_timestamp
|
|
346
|
+
ON ${s}.application_versions (shard_key, version_timestamp DESC)`,
|
|
347
|
+
},
|
|
348
|
+
{
|
|
349
|
+
sql: `CREATE INDEX IF NOT EXISTS idx_application_versions_owner_timestamp
|
|
350
|
+
ON ${s}.application_versions (shard_key, application_name, version_timestamp DESC)`,
|
|
351
|
+
},
|
|
352
|
+
];
|
|
353
|
+
}
|
|
354
|
+
function migrationTwo(s) {
|
|
355
|
+
return [
|
|
356
|
+
{
|
|
357
|
+
sql: `CREATE OR REPLACE FUNCTION ${s}.claim_gate(name text, slots int4) RETURNS boolean
|
|
358
|
+
LANGUAGE plpgsql VOLATILE AS $$
|
|
359
|
+
DECLARE
|
|
360
|
+
first int4 := floor(random() * slots)::int4;
|
|
361
|
+
BEGIN
|
|
362
|
+
FOR i IN 0 .. slots - 1 LOOP
|
|
363
|
+
IF pg_try_advisory_xact_lock(hashtext(name), (first + i) % slots) THEN
|
|
364
|
+
RETURN true;
|
|
365
|
+
END IF;
|
|
366
|
+
END LOOP;
|
|
367
|
+
RETURN false;
|
|
368
|
+
END $$`,
|
|
369
|
+
},
|
|
370
|
+
];
|
|
371
|
+
}
|
|
372
|
+
function getShardedMigrations(schema) {
|
|
373
|
+
const quotedSchema = quoteIdentifier(schema);
|
|
374
|
+
return [migrationOne(quotedSchema), migrationTwo(quotedSchema)];
|
|
375
|
+
}
|
|
376
|
+
exports.getShardedMigrations = getShardedMigrations;
|
|
377
|
+
exports.LATEST_VERSION = getShardedMigrations('dbos').length;
|
|
378
|
+
function quoteIdentifier(name) {
|
|
379
|
+
return `"${name.replace(/"/g, '""')}"`;
|
|
380
|
+
}
|
|
381
|
+
async function currentVersion(sysdb) {
|
|
382
|
+
const client = await sysdb.connect();
|
|
383
|
+
try {
|
|
384
|
+
return await recordedVersion(client, sysdb.schemaName);
|
|
385
|
+
}
|
|
386
|
+
finally {
|
|
387
|
+
client.release();
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
exports.currentVersion = currentVersion;
|
|
391
|
+
async function recordedVersion(client, schema) {
|
|
392
|
+
const exists = await client.query(`SELECT 1 FROM information_schema.tables WHERE table_schema = $1 AND table_name = 'dbos_migrations'`, [schema]);
|
|
393
|
+
if (exists.rows.length === 0) {
|
|
394
|
+
return 0;
|
|
395
|
+
}
|
|
396
|
+
try {
|
|
397
|
+
const { rows } = await client.query(`SELECT version FROM ${quoteIdentifier(schema)}.dbos_migrations WHERE shard_key = $1`, [schema_1.GLOBAL_SHARD_KEY]);
|
|
398
|
+
return rows.length > 0 && rows[0].version !== null ? Number(rows[0].version) : 0;
|
|
399
|
+
}
|
|
400
|
+
catch (e) {
|
|
401
|
+
if ((0, system_database_1.isPgDatabaseError)(e) && e.code === '42P01') {
|
|
402
|
+
return 0;
|
|
403
|
+
}
|
|
404
|
+
throw e;
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
async function citusInstalled(client) {
|
|
408
|
+
const { rows } = await client.query(`SELECT 1 FROM pg_extension WHERE extname = 'citus'`);
|
|
409
|
+
return rows.length > 0;
|
|
410
|
+
}
|
|
411
|
+
exports.citusInstalled = citusInstalled;
|
|
412
|
+
async function distributeOnCitus(client, table) {
|
|
413
|
+
if (!(await citusInstalled(client))) {
|
|
414
|
+
return;
|
|
415
|
+
}
|
|
416
|
+
const { rows } = await client.query(`SELECT 1 FROM pg_dist_partition WHERE logicalrelid = CAST($1 AS regclass)`, [
|
|
417
|
+
table,
|
|
418
|
+
]);
|
|
419
|
+
if (rows.length === 0) {
|
|
420
|
+
const schema = table.slice(0, table.lastIndexOf('.'));
|
|
421
|
+
const name = table.slice(table.lastIndexOf('.') + 1);
|
|
422
|
+
const colocateWith = name === 'dbos_migrations' ? 'none' : `${schema}.dbos_migrations`;
|
|
423
|
+
await client.query(`SELECT create_distributed_table($1, 'shard_key', colocate_with => $2)`, [table, colocateWith]);
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
async function runMigrations(sysdb) {
|
|
427
|
+
if ((await currentVersion(sysdb)) >= exports.LATEST_VERSION) {
|
|
428
|
+
return;
|
|
429
|
+
}
|
|
430
|
+
const key = (0, locks_1.lockKey)(`dbos.migrations.${sysdb.schemaName}`);
|
|
431
|
+
const deadline = performance.now() + MIGRATION_LOCK_TIMEOUT_MS;
|
|
432
|
+
for (;;) {
|
|
433
|
+
const client = await sysdb.connect();
|
|
434
|
+
let destroy = true;
|
|
435
|
+
try {
|
|
436
|
+
const lock = await (0, locks_1.tryAdvisoryLock)(client, key, { name: 'migration', discard: true, logger: sysdb.logger });
|
|
437
|
+
try {
|
|
438
|
+
if (lock.acquired || performance.now() >= deadline) {
|
|
439
|
+
if (!lock.acquired) {
|
|
440
|
+
sysdb.logger.warn(`Could not acquire the sharded migration lock within ${MIGRATION_LOCK_TIMEOUT_MS / 1000}s. Migrating without it.`);
|
|
441
|
+
}
|
|
442
|
+
await migrate(sysdb, client);
|
|
443
|
+
return;
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
finally {
|
|
447
|
+
destroy = await lock.release();
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
finally {
|
|
451
|
+
client.release(destroy);
|
|
452
|
+
}
|
|
453
|
+
await (0, utils_1.sleepms)(1000);
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
exports.runMigrations = runMigrations;
|
|
457
|
+
async function migrate(sysdb, client) {
|
|
458
|
+
const schema = sysdb.schemaName;
|
|
459
|
+
const version = await recordedVersion(client, schema);
|
|
460
|
+
if (version >= exports.LATEST_VERSION) {
|
|
461
|
+
return;
|
|
462
|
+
}
|
|
463
|
+
sysdb.logger.info(`Migrating sharded system database schema ${schema} from version ${version} to ${exports.LATEST_VERSION}`);
|
|
464
|
+
const quoted = quoteIdentifier(schema);
|
|
465
|
+
for (const migration of getShardedMigrations(schema).slice(version)) {
|
|
466
|
+
for (const statement of migration) {
|
|
467
|
+
await client.query(statement.sql);
|
|
468
|
+
if (statement.creates !== undefined) {
|
|
469
|
+
await distributeOnCitus(client, `${quoted}.${statement.creates}`);
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
await client.query(`INSERT INTO ${quoted}.dbos_migrations (shard_key, version) VALUES ($1, $2)
|
|
474
|
+
ON CONFLICT (shard_key) DO UPDATE SET version = GREATEST(${quoted}.dbos_migrations.version, EXCLUDED.version)`, [schema_1.GLOBAL_SHARD_KEY, exports.LATEST_VERSION]);
|
|
475
|
+
}
|
|
476
|
+
async function verifyMigrations(sysdb) {
|
|
477
|
+
const current = await currentVersion(sysdb);
|
|
478
|
+
if (current < exports.LATEST_VERSION) {
|
|
479
|
+
throw new error_1.DBOSInitializationError(`Sharded system database schema ${sysdb.schemaName} is at version ${current}, but this version of DBOS ` +
|
|
480
|
+
`requires ${exports.LATEST_VERSION}. This process is configured with runMigrations disabled, so it will not ` +
|
|
481
|
+
'migrate it: either migrate the system database out of band (`npx dbos schema --sharding`) or launch ' +
|
|
482
|
+
'with runMigrations enabled.');
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
exports.verifyMigrations = verifyMigrations;
|
|
486
|
+
//# sourceMappingURL=migrations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migrations.js","sourceRoot":"","sources":["../../../src/sharding/migrations.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
// Copyright (c) 2026 DBOS, Inc. All rights reserved.
|
|
2
|
+
//
|
|
3
|
+
// This file is part of Transact Enterprise, proprietary software licensed under the
|
|
4
|
+
// DBOS Conductor Software License: https://www.dbos.dev/conductor-license
|
|
5
|
+
// You may not use, copy, modify, or distribute this file except as that license permits.
|
|
6
|
+
// Disabling or circumventing the entitlement checks in @dbos-inc/dbos-sdk's src/enterprise.ts
|
|
7
|
+
// that gate it is a material breach of that license.
|
|
8
|
+
export declare const GLOBAL_SHARD_KEY = "__dbos_global__";
|
|
9
|
+
//# sourceMappingURL=schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../src/sharding/schema.ts"],"names":[],"mappings":";;;;;;;AAGA,eAAO,MAAM,gBAAgB,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// Copyright (c) 2026 DBOS, Inc. All rights reserved.
|
|
2
|
+
//
|
|
3
|
+
// This file is part of Transact Enterprise, proprietary software licensed under the
|
|
4
|
+
// DBOS Conductor Software License: https://www.dbos.dev/conductor-license
|
|
5
|
+
// You may not use, copy, modify, or distribute this file except as that license permits.
|
|
6
|
+
// Disabling or circumventing the entitlement checks in @dbos-inc/dbos-sdk's src/enterprise.ts
|
|
7
|
+
// that gate it is a material breach of that license.
|
|
8
|
+
"use strict";
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.GLOBAL_SHARD_KEY = void 0;
|
|
11
|
+
exports.GLOBAL_SHARD_KEY = '__dbos_global__';
|
|
12
|
+
//# sourceMappingURL=schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../../src/sharding/schema.ts"],"names":[],"mappings":";;;;;;;;;;AAGa,QAAA,gBAAgB,GAAG,iBAAiB,CAAC"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
// Copyright (c) 2026 DBOS, Inc. All rights reserved.
|
|
2
|
+
//
|
|
3
|
+
// This file is part of Transact Enterprise, proprietary software licensed under the
|
|
4
|
+
// DBOS Conductor Software License: https://www.dbos.dev/conductor-license
|
|
5
|
+
// You may not use, copy, modify, or distribute this file except as that license permits.
|
|
6
|
+
// Disabling or circumventing the entitlement checks in @dbos-inc/dbos-sdk's src/enterprise.ts
|
|
7
|
+
// that gate it is a material breach of that license.
|
|
8
|
+
import type { ClientBase, Pool, PoolClient } from 'pg';
|
|
9
|
+
import type { ShardedSystemDatabaseOptions } from '@dbos-inc/dbos-sdk/internal/enterprise';
|
|
10
|
+
import { SystemDatabase, type ApplicationRowCounts, type DebounceResult, type DequeueStopReason, type InsertWorkflowResult, type RecoveredWorkflow, type SystemDatabaseStoredResult, type WorkflowScheduleInternal, type WorkflowStatusInternal } from '@dbos-inc/dbos-sdk/internal/system_database';
|
|
11
|
+
import { GetWorkflowsInput, WorkflowIDReusePolicy } from '@dbos-inc/dbos-sdk/internal/workflow';
|
|
12
|
+
import type { WorkflowQueue } from '@dbos-inc/dbos-sdk/internal/wfqueue';
|
|
13
|
+
type InitResult = Awaited<ReturnType<SystemDatabase['initWorkflowStatus']>>;
|
|
14
|
+
export declare class ShardedSystemDatabase extends SystemDatabase {
|
|
15
|
+
#private;
|
|
16
|
+
discoveryIntervalMs: number;
|
|
17
|
+
discoveryEmptyIntervalMs: number;
|
|
18
|
+
claimSlotsPerKey: number;
|
|
19
|
+
dbPollingIntervalEventMs: number;
|
|
20
|
+
constructor(options: ShardedSystemDatabaseOptions);
|
|
21
|
+
get sharded(): boolean;
|
|
22
|
+
resolvedKey(workflowID: string, explicit?: string): string | undefined;
|
|
23
|
+
shardKeyOf(workflowID: string, explicit?: string): string;
|
|
24
|
+
scopeKey(): string;
|
|
25
|
+
singleKey(keys: Iterable<string>, operation: string): string | undefined;
|
|
26
|
+
groupByKey(workflowIDs: Iterable<string>): Map<string, string[]>;
|
|
27
|
+
wf(alias: string | undefined, workflowID: string, params: unknown[], column?: string, shardKey?: string): string;
|
|
28
|
+
wfIn(alias: string | undefined, workflowIDs: string[], params: unknown[]): string;
|
|
29
|
+
wfJoin(left: string, right: string): string;
|
|
30
|
+
wfValues(workflowID: string, shardKey?: string): Record<string, unknown>;
|
|
31
|
+
parentValues(parentWorkflowID: string | undefined): Record<string, unknown>;
|
|
32
|
+
childValues(childWorkflowID: string | null | undefined): Record<string, unknown>;
|
|
33
|
+
wfColumns(workflowID: string, params: unknown[]): [string, string][];
|
|
34
|
+
keyConflict(...columns: string[]): string;
|
|
35
|
+
isCitus(): Promise<boolean>;
|
|
36
|
+
backgroundJobLock<T>(jobName: string, callback: (acquired: boolean) => Promise<T>): Promise<T>;
|
|
37
|
+
outcomeInOneStatement(): Promise<boolean>;
|
|
38
|
+
insertRows<T extends object = object>(client: ClientBase | Pool, table: string, columns: string[], rows: unknown[][], suffix?: string): Promise<T[]>;
|
|
39
|
+
claimGate(queueName: string, partitionKey: string | undefined, params: unknown[]): string;
|
|
40
|
+
scoped(alias: string | undefined, params: unknown[]): string;
|
|
41
|
+
scopedColumns(params: unknown[]): [string, string][];
|
|
42
|
+
global(alias: string | undefined, params: unknown[]): string;
|
|
43
|
+
globalValues(): Record<string, unknown>;
|
|
44
|
+
keyIn(alias: string | undefined, shardKeys: string[], params: unknown[], column?: string): string;
|
|
45
|
+
keyColumn(alias: string | undefined, column?: string): string | undefined;
|
|
46
|
+
keyHint(workflowID: string): string | undefined;
|
|
47
|
+
scheduleValues(schedule: WorkflowScheduleInternal): Record<string, unknown>;
|
|
48
|
+
scheduleKeyColumn(): string | undefined;
|
|
49
|
+
runMigrations(): Promise<void>;
|
|
50
|
+
verifyMigrations(): Promise<void>;
|
|
51
|
+
isSerializationConflict(e: unknown): boolean;
|
|
52
|
+
static requireKey(status: WorkflowStatusInternal): void;
|
|
53
|
+
protected insertWorkflowStatus(client: ClientBase, initStatus: WorkflowStatusInternal, creatorXid: string | null): Promise<InsertWorkflowResult>;
|
|
54
|
+
debounceDelayedWorkflow(): Promise<DebounceResult>;
|
|
55
|
+
enqueueWorkflows(): Promise<Set<string>>;
|
|
56
|
+
renameApplication(): Promise<ApplicationRowCounts>;
|
|
57
|
+
precheckOwner(workflowID: string | undefined): Promise<void>;
|
|
58
|
+
initChildWorkflowStatus(initStatus: WorkflowStatusInternal, creatorXid: string, parentWorkflowID: string, parentFunctionID: number, startTimeEpochMs: number, endTimeEpochMs: number, reusePolicy?: WorkflowIDReusePolicy): Promise<InitResult>;
|
|
59
|
+
protected recordChild(client: PoolClient, status: WorkflowStatusInternal, parentWorkflowID: string, parentFunctionID: number, startTimeEpochMs: number, endTimeEpochMs: number): Promise<void>;
|
|
60
|
+
protected keyedMessage(destinationID: string, shardKey: string | undefined, idempotencyKey: string | undefined, workflowID: string | undefined, functionID: number | undefined): {
|
|
61
|
+
key: string;
|
|
62
|
+
idempotencyKey: string | undefined;
|
|
63
|
+
};
|
|
64
|
+
send(workflowID: string, functionID: number, destinationID: string, message: string | null, topic: string | undefined, serialization: string | null, idempotencyKey?: string, shardKey?: string): Promise<void>;
|
|
65
|
+
sendDirect(destinationID: string, message: string | null, topic: string | undefined, serialization: string | null, idempotencyKey?: string, client?: ClientBase, shardKey?: string): Promise<void>;
|
|
66
|
+
sendFromStep(workflowID: string, destinationID: string, message: string | null, topic: string | undefined, serialization: string | null, idempotencyKey?: string, shardKey?: string): Promise<void>;
|
|
67
|
+
runTransactionalStep(workflowID: string, functionID: number, functionName: string, callback: (client: PoolClient) => Promise<string | null>): Promise<SystemDatabaseStoredResult | undefined>;
|
|
68
|
+
getWorkflowStatus(workflowID: string, callerID?: string, callerFN?: number): Promise<WorkflowStatusInternal | null>;
|
|
69
|
+
keyOfBatch(workflowIDs: string[], operation: string): string | undefined;
|
|
70
|
+
deadLetterWorkflows(workflowIDs: string[], minRecoveryAttempts: number): Promise<void>;
|
|
71
|
+
resumeWorkflows(workflowIDs: string[], queueName?: string): Promise<void>;
|
|
72
|
+
listWorkflows(input: GetWorkflowsInput, options?: {
|
|
73
|
+
keyedIDs?: boolean;
|
|
74
|
+
}): Promise<WorkflowStatusInternal[]>;
|
|
75
|
+
getWorkflowStatuses(workflowIDs: string[]): Promise<Map<string, WorkflowStatusInternal>>;
|
|
76
|
+
checkFirstWorkflowId(workflowIds: string[]): Promise<string | undefined>;
|
|
77
|
+
checkCompletedWorkflowIds(workflowIds: string[]): Promise<string[]>;
|
|
78
|
+
childrenOf(parents: [string, string][]): Promise<[string, string][]>;
|
|
79
|
+
protected getDirectChildren(): Promise<string[]>;
|
|
80
|
+
cancelWorkflows(workflowIDs: string[], cancelChildren?: boolean): Promise<void>;
|
|
81
|
+
deleteWorkflows(workflowIDs: string[], deleteChildren?: boolean): Promise<void>;
|
|
82
|
+
bulkForkWorkflows(originalWorkflowIDs: string[], forkedWorkflowIDs: string[], startSteps: number[], options?: {
|
|
83
|
+
applicationVersion?: string;
|
|
84
|
+
timeoutMS?: number;
|
|
85
|
+
queueName?: string;
|
|
86
|
+
queuePartitionKey?: string;
|
|
87
|
+
replacementChildren?: Record<string, string>;
|
|
88
|
+
}): Promise<string[]>;
|
|
89
|
+
dequeueScopes(queueName: string): Promise<(string | undefined)[]>;
|
|
90
|
+
claimStartableWorkflows(queue: WorkflowQueue, executorID: string, appVersion: string, queuePartitionKey?: string, localRunningCount?: number, partitionLocalRunningCount?: number, ownerXid?: string | null, isLatestVersion?: boolean): Promise<{
|
|
91
|
+
claimedIDs: string[];
|
|
92
|
+
stopReason?: DequeueStopReason;
|
|
93
|
+
}>;
|
|
94
|
+
findAndMarkStartablePartitionedWorkflows(queue: WorkflowQueue, executorID: string, appVersion: string, maxTasks?: number, ownerXid?: string | null, isLatestVersion?: boolean): Promise<string[]>;
|
|
95
|
+
getQueuePartitions(queueName: string): Promise<string[]>;
|
|
96
|
+
discoverScopes(queueName: string): Promise<(string | undefined)[]>;
|
|
97
|
+
cancelTimedOutWorkflows(limit: number): Promise<string[]>;
|
|
98
|
+
reenqueueWorkflowsForRecovery(executorID: string, appVersion: string, recoveryQueueName: string): Promise<RecoveredWorkflow[]>;
|
|
99
|
+
}
|
|
100
|
+
export {};
|
|
101
|
+
//# sourceMappingURL=sys_db.d.ts.map
|