@pg-boss/dashboard 1.0.1 → 1.1.1
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 +25 -173
- package/build/client/assets/MenuTrigger-CEHCnGow.js +1 -0
- package/build/client/assets/{_index-Bcg_-XSd.js → _index-9fLquIe1.js} +1 -1
- package/build/client/assets/{badge-Cd8v3tl3.js → badge-B5ZugmiV.js} +1 -1
- package/build/client/assets/{button-BaXUPm8v.js → button-Djse56Dx.js} +1 -1
- package/build/client/assets/{chevron-down-xu6Uceu-.js → chevron-down-B4tDL9Ah.js} +1 -1
- package/build/client/assets/chunk-LFPYN7LY-Cj1DJmJR.js +26 -0
- package/build/client/assets/{createLucideIcon-BXGwbdrh.js → createLucideIcon-B0YqJFaz.js} +1 -1
- package/build/client/assets/db-link-DmvfwdX4.js +1 -0
- package/build/client/assets/dialog-CQzw3QVH.js +1 -0
- package/build/client/assets/{entry.client-COnaNoy-.js → entry.client-Szv-xmaE.js} +4 -4
- package/build/client/assets/{error-card-DmoxS3Ao.js → error-card-CXoOCvsg.js} +1 -1
- package/build/client/assets/{filter-select-mMC79WOR.js → filter-select-DXyBBVm8.js} +1 -1
- package/build/client/assets/{index-DhMkYPMa.js → index-x2yWco1W.js} +1 -1
- package/build/client/assets/{jobs-DtmTCs8I.js → jobs-CM6xcK-O.js} +1 -1
- package/build/client/assets/manifest-acaa4b8e.js +1 -0
- package/build/client/assets/{pagination-NfhvsUbp.js → pagination-C4yyCmBA.js} +1 -1
- package/build/client/assets/{queues._index-Cw1B49mg.js → queues._index-Dn3ieC5d.js} +1 -1
- package/build/client/assets/{queues._name-D0cG_qDX.js → queues._name-GrviLLx2.js} +1 -1
- package/build/client/assets/{queues._name.jobs._jobId-uJ3dfM3J.js → queues._name.jobs._jobId-s_wYs79w.js} +1 -1
- package/build/client/assets/{queues.create-BGXDhJ3m.js → queues.create-Ch3Mqw52.js} +1 -1
- package/build/client/assets/root-Bpb4WtY4.css +1 -0
- package/build/client/assets/{root-NWrBrGvr.js → root-D0qqtdF7.js} +1 -1
- package/build/client/assets/{schedules-DzgBEayh.js → schedules-DwnuuhxF.js} +1 -1
- package/build/client/assets/{schedules._name._key-i42S9kw2.js → schedules._name._key-DJn-u3Cm.js} +1 -1
- package/build/client/assets/{schedules.new-Dt78KptL.js → schedules.new-CQuE2Uhz.js} +1 -1
- package/build/client/assets/{send-0eWgiWNl.js → send-DVfuC6NR.js} +1 -1
- package/build/client/assets/{table-CTo0I5HG.js → table-CtSLyG7m.js} +1 -1
- package/build/client/assets/useOpenInteractionType-Ss_6xZdw.js +12 -0
- package/build/client/assets/{warnings-BhQM6lFV.js → warnings-DqRQYomb.js} +1 -1
- package/build/server/assets/auth.server-DgTIakNo.js +17 -0
- package/build/server/assets/server-build.js +305 -39
- package/build/server/index.js +5 -0
- package/package.json +16 -15
- package/build/client/assets/MenuTrigger-SThQHnlb.js +0 -1
- package/build/client/assets/chunk-JZWAC4HX-DC8i-F7r.js +0 -26
- package/build/client/assets/db-link-CtPnIrIr.js +0 -1
- package/build/client/assets/dialog-Bl8T588f.js +0 -1
- package/build/client/assets/manifest-25954681.js +0 -1
- package/build/client/assets/root-DJRlbyb5.css +0 -1
- package/build/client/assets/useOpenInteractionType-C_L8nZ_l.js +0 -12
|
@@ -1428,6 +1428,7 @@ function createTableQueue(schema) {
|
|
|
1428
1428
|
warning_queued int NOT NULL default 0,
|
|
1429
1429
|
active_count int NOT NULL default 0,
|
|
1430
1430
|
total_count int NOT NULL default 0,
|
|
1431
|
+
heartbeat_seconds int,
|
|
1431
1432
|
singletons_active text[],
|
|
1432
1433
|
monitor_on timestamp with time zone,
|
|
1433
1434
|
maintain_on timestamp with time zone,
|
|
@@ -1610,11 +1611,13 @@ function createTableJob(schema) {
|
|
|
1610
1611
|
keep_until timestamp with time zone NOT NULL default now() + interval '${QUEUE_DEFAULTS.retention_seconds}',
|
|
1611
1612
|
output jsonb,
|
|
1612
1613
|
dead_letter text,
|
|
1613
|
-
policy text
|
|
1614
|
+
policy text,
|
|
1615
|
+
heartbeat_on timestamp with time zone,
|
|
1616
|
+
heartbeat_seconds int
|
|
1614
1617
|
) PARTITION BY LIST (name)
|
|
1615
1618
|
`;
|
|
1616
1619
|
}
|
|
1617
|
-
const JOB_COLUMNS_MIN = 'id, name, data, expire_seconds as "expireInSeconds", group_id as "groupId", group_tier as "groupTier"';
|
|
1620
|
+
const JOB_COLUMNS_MIN = 'id, name, data, expire_seconds as "expireInSeconds", heartbeat_seconds as "heartbeatSeconds", group_id as "groupId", group_tier as "groupTier"';
|
|
1618
1621
|
const JOB_COLUMNS_ALL = `${JOB_COLUMNS_MIN},
|
|
1619
1622
|
policy,
|
|
1620
1623
|
state,
|
|
@@ -1629,6 +1632,7 @@ const JOB_COLUMNS_ALL = `${JOB_COLUMNS_MIN},
|
|
|
1629
1632
|
singleton_key as "singletonKey",
|
|
1630
1633
|
singleton_on as "singletonOn",
|
|
1631
1634
|
deletion_seconds as "deleteAfterSeconds",
|
|
1635
|
+
heartbeat_on as "heartbeatOn",
|
|
1632
1636
|
created_on as "createdOn",
|
|
1633
1637
|
completed_on as "completedOn",
|
|
1634
1638
|
keep_until as "keepUntil",
|
|
@@ -1682,7 +1686,8 @@ function createQueueFunction(schema) {
|
|
|
1682
1686
|
warning_queued,
|
|
1683
1687
|
dead_letter,
|
|
1684
1688
|
partition,
|
|
1685
|
-
table_name
|
|
1689
|
+
table_name,
|
|
1690
|
+
heartbeat_seconds
|
|
1686
1691
|
)
|
|
1687
1692
|
VALUES (
|
|
1688
1693
|
queue_name,
|
|
@@ -1697,7 +1702,8 @@ function createQueueFunction(schema) {
|
|
|
1697
1702
|
COALESCE((options->>'warningQueueSize')::int, ${QUEUE_DEFAULTS.warning_queued}),
|
|
1698
1703
|
options->>'deadLetter',
|
|
1699
1704
|
COALESCE((options->>'partition')::bool, ${QUEUE_DEFAULTS.partition}),
|
|
1700
|
-
tablename
|
|
1705
|
+
tablename,
|
|
1706
|
+
(options->>'heartbeatSeconds')::int
|
|
1701
1707
|
)
|
|
1702
1708
|
ON CONFLICT DO NOTHING
|
|
1703
1709
|
RETURNING created_on
|
|
@@ -1854,6 +1860,9 @@ function updateQueue(schema, { deadLetter } = {}) {
|
|
|
1854
1860
|
retention_seconds = COALESCE((o.data->>'retentionSeconds')::int, retention_seconds),
|
|
1855
1861
|
deletion_seconds = COALESCE((o.data->>'deleteAfterSeconds')::int, deletion_seconds),
|
|
1856
1862
|
warning_queued = COALESCE((o.data->>'warningQueueSize')::int, warning_queued),
|
|
1863
|
+
heartbeat_seconds = CASE WHEN o.data ? 'heartbeatSeconds'
|
|
1864
|
+
THEN (o.data->>'heartbeatSeconds')::int
|
|
1865
|
+
ELSE heartbeat_seconds END,
|
|
1857
1866
|
${deadLetter === void 0 ? "" : `dead_letter = CASE WHEN '${deadLetter}' IS DISTINCT FROM dead_letter THEN '${deadLetter}' ELSE dead_letter END,`}
|
|
1858
1867
|
updated_on = now()
|
|
1859
1868
|
FROM options o
|
|
@@ -1875,6 +1884,7 @@ function getQueues$1(schema, names) {
|
|
|
1875
1884
|
q.retention_seconds as "retentionSeconds",
|
|
1876
1885
|
q.deletion_seconds as "deleteAfterSeconds",
|
|
1877
1886
|
q.partition,
|
|
1887
|
+
q.heartbeat_seconds as "heartbeatSeconds",
|
|
1878
1888
|
q.dead_letter as "deadLetter",
|
|
1879
1889
|
q.deferred_count as "deferredCount",
|
|
1880
1890
|
q.warning_queued as "warningQueueSize",
|
|
@@ -2091,6 +2101,7 @@ function fetchNextJob(options) {
|
|
|
2091
2101
|
UPDATE ${schema}.${table} j SET
|
|
2092
2102
|
state = '${JOB_STATES.active}',
|
|
2093
2103
|
started_on = now(),
|
|
2104
|
+
heartbeat_on = now(),
|
|
2094
2105
|
retry_count = CASE WHEN started_on IS NOT NULL THEN retry_count + 1 ELSE retry_count END
|
|
2095
2106
|
FROM ${finalCte}
|
|
2096
2107
|
WHERE name = '${name}' AND j.id = ${finalCte}.id
|
|
@@ -2172,7 +2183,8 @@ function insertJobs(schema, { table, name, returnId = true }) {
|
|
|
2172
2183
|
retry_backoff,
|
|
2173
2184
|
retry_delay_max,
|
|
2174
2185
|
policy,
|
|
2175
|
-
dead_letter
|
|
2186
|
+
dead_letter,
|
|
2187
|
+
heartbeat_seconds
|
|
2176
2188
|
)
|
|
2177
2189
|
SELECT
|
|
2178
2190
|
COALESCE(id, gen_random_uuid()) as id,
|
|
@@ -2195,7 +2207,8 @@ function insertJobs(schema, { table, name, returnId = true }) {
|
|
|
2195
2207
|
COALESCE("retryBackoff", q.retry_backoff, false) as retry_backoff,
|
|
2196
2208
|
COALESCE("retryDelayMax", q.retry_delay_max) as retry_delay_max,
|
|
2197
2209
|
q.policy,
|
|
2198
|
-
COALESCE("deadLetter", q.dead_letter) as dead_letter
|
|
2210
|
+
COALESCE("deadLetter", q.dead_letter) as dead_letter,
|
|
2211
|
+
COALESCE("heartbeatSeconds", q.heartbeat_seconds) as heartbeat_seconds
|
|
2199
2212
|
FROM (
|
|
2200
2213
|
SELECT *,
|
|
2201
2214
|
CASE
|
|
@@ -2219,7 +2232,8 @@ function insertJobs(schema, { table, name, returnId = true }) {
|
|
|
2219
2232
|
"expireInSeconds" integer,
|
|
2220
2233
|
"deleteAfterSeconds" integer,
|
|
2221
2234
|
"retentionSeconds" integer,
|
|
2222
|
-
"deadLetter" text
|
|
2235
|
+
"deadLetter" text,
|
|
2236
|
+
"heartbeatSeconds" integer
|
|
2223
2237
|
)
|
|
2224
2238
|
) j
|
|
2225
2239
|
JOIN ${schema}.queue q ON q.name = '${name}'
|
|
@@ -2240,6 +2254,27 @@ function failJobsByTimeout(schema, table, queues) {
|
|
|
2240
2254
|
const output = `'{ "value": { "message": "job timed out" } }'::jsonb`;
|
|
2241
2255
|
return locked(schema, failJobs(schema, table, where, output), table + "failJobsByTimeout");
|
|
2242
2256
|
}
|
|
2257
|
+
function failJobsByHeartbeat(schema, table, queues) {
|
|
2258
|
+
const where = `state = '${JOB_STATES.active}'
|
|
2259
|
+
AND heartbeat_seconds IS NOT NULL
|
|
2260
|
+
AND (heartbeat_on + heartbeat_seconds * interval '1s') < now()
|
|
2261
|
+
AND name = ANY(${serializeArrayParam(queues)})`;
|
|
2262
|
+
const output = `'{ "value": { "message": "job heartbeat timeout" } }'::jsonb`;
|
|
2263
|
+
return locked(schema, failJobs(schema, table, where, output), table + "failJobsByHeartbeat");
|
|
2264
|
+
}
|
|
2265
|
+
function touchJobs(schema, table) {
|
|
2266
|
+
return `
|
|
2267
|
+
WITH results AS (
|
|
2268
|
+
UPDATE ${schema}.${table}
|
|
2269
|
+
SET heartbeat_on = now()
|
|
2270
|
+
WHERE name = $1
|
|
2271
|
+
AND id IN (SELECT UNNEST($2::uuid[]))
|
|
2272
|
+
AND state = '${JOB_STATES.active}'
|
|
2273
|
+
RETURNING 1
|
|
2274
|
+
)
|
|
2275
|
+
SELECT COUNT(*) FROM results
|
|
2276
|
+
`;
|
|
2277
|
+
}
|
|
2243
2278
|
function failJobs(schema, table, where, output) {
|
|
2244
2279
|
return `
|
|
2245
2280
|
WITH deleted_jobs AS (
|
|
@@ -2272,7 +2307,9 @@ function failJobs(schema, table, where, output) {
|
|
|
2272
2307
|
keep_until,
|
|
2273
2308
|
policy,
|
|
2274
2309
|
output,
|
|
2275
|
-
dead_letter
|
|
2310
|
+
dead_letter,
|
|
2311
|
+
heartbeat_on,
|
|
2312
|
+
heartbeat_seconds
|
|
2276
2313
|
)
|
|
2277
2314
|
SELECT
|
|
2278
2315
|
id,
|
|
@@ -2310,7 +2347,9 @@ function failJobs(schema, table, where, output) {
|
|
|
2310
2347
|
keep_until,
|
|
2311
2348
|
policy,
|
|
2312
2349
|
${output},
|
|
2313
|
-
dead_letter
|
|
2350
|
+
dead_letter,
|
|
2351
|
+
NULL as heartbeat_on,
|
|
2352
|
+
heartbeat_seconds
|
|
2314
2353
|
FROM deleted_jobs
|
|
2315
2354
|
ON CONFLICT DO NOTHING
|
|
2316
2355
|
RETURNING *
|
|
@@ -2340,7 +2379,9 @@ function failJobs(schema, table, where, output) {
|
|
|
2340
2379
|
keep_until,
|
|
2341
2380
|
policy,
|
|
2342
2381
|
output,
|
|
2343
|
-
dead_letter
|
|
2382
|
+
dead_letter,
|
|
2383
|
+
heartbeat_on,
|
|
2384
|
+
heartbeat_seconds
|
|
2344
2385
|
)
|
|
2345
2386
|
SELECT
|
|
2346
2387
|
id,
|
|
@@ -2366,7 +2407,9 @@ function failJobs(schema, table, where, output) {
|
|
|
2366
2407
|
keep_until,
|
|
2367
2408
|
policy,
|
|
2368
2409
|
${output},
|
|
2369
|
-
dead_letter
|
|
2410
|
+
dead_letter,
|
|
2411
|
+
NULL as heartbeat_on,
|
|
2412
|
+
heartbeat_seconds
|
|
2370
2413
|
FROM deleted_jobs
|
|
2371
2414
|
WHERE id NOT IN (SELECT id from retried_jobs)
|
|
2372
2415
|
RETURNING *
|
|
@@ -2579,7 +2622,7 @@ const POLICY = {
|
|
|
2579
2622
|
MAX_RETENTION_DAYS: 365
|
|
2580
2623
|
};
|
|
2581
2624
|
function assertObjectName(value, name = "Name") {
|
|
2582
|
-
assert(/^[\w
|
|
2625
|
+
assert(/^[\w.\-/]+$/.test(value), `${name} can only contain alphanumeric characters, underscores, hyphens, periods, or forward slashes`);
|
|
2583
2626
|
}
|
|
2584
2627
|
function validateQueueArgs(config = {}) {
|
|
2585
2628
|
assert(!("deadLetter" in config) || config.deadLetter === null || typeof config.deadLetter === "string", "deadLetter must be a string");
|
|
@@ -2590,6 +2633,7 @@ function validateQueueArgs(config = {}) {
|
|
|
2590
2633
|
validateExpirationConfig(config);
|
|
2591
2634
|
validateRetentionConfig(config);
|
|
2592
2635
|
validateDeletionConfig(config);
|
|
2636
|
+
validateHeartbeatConfig(config);
|
|
2593
2637
|
}
|
|
2594
2638
|
function checkSendArgs(args) {
|
|
2595
2639
|
let name, data, options;
|
|
@@ -2618,6 +2662,7 @@ function checkSendArgs(args) {
|
|
|
2618
2662
|
validateRetentionConfig(options);
|
|
2619
2663
|
validateDeletionConfig(options);
|
|
2620
2664
|
validateGroupConfig(options);
|
|
2665
|
+
validateHeartbeatConfig(options);
|
|
2621
2666
|
return { name, data, options };
|
|
2622
2667
|
}
|
|
2623
2668
|
function validateGroupConfig(config) {
|
|
@@ -2697,6 +2742,7 @@ function checkWorkArgs(name, args) {
|
|
|
2697
2742
|
assert(!("priority" in options) || typeof options.priority === "boolean", "priority must be a boolean");
|
|
2698
2743
|
assert(!("localConcurrency" in options) || Number.isInteger(options.localConcurrency) && options.localConcurrency >= 1, "localConcurrency must be an integer >= 1");
|
|
2699
2744
|
validateGroupConcurrencyConfig(options);
|
|
2745
|
+
validateHeartbeatRefreshConfig(options);
|
|
2700
2746
|
return { options, callback };
|
|
2701
2747
|
}
|
|
2702
2748
|
function checkFetchArgs(name, options) {
|
|
@@ -2783,6 +2829,19 @@ function validateRetryConfig(config) {
|
|
|
2783
2829
|
assert(!("retryDelayMax" in config) || config.retryDelayMax === null || config.retryBackoff === true, "retryDelayMax can only be set if retryBackoff is true");
|
|
2784
2830
|
assert(!("retryDelayMax" in config) || config.retryDelayMax === null || Number.isInteger(config.retryDelayMax) && config.retryDelayMax >= 0, "retryDelayMax must be an integer >= 0");
|
|
2785
2831
|
}
|
|
2832
|
+
function validateHeartbeatConfig(config) {
|
|
2833
|
+
assert(
|
|
2834
|
+
!("heartbeatSeconds" in config) || config.heartbeatSeconds === null || Number.isInteger(config.heartbeatSeconds) && config.heartbeatSeconds >= 10,
|
|
2835
|
+
"heartbeatSeconds must be an integer >= 10"
|
|
2836
|
+
);
|
|
2837
|
+
}
|
|
2838
|
+
function validateHeartbeatRefreshConfig(config) {
|
|
2839
|
+
if (!("heartbeatRefreshSeconds" in config) || config.heartbeatRefreshSeconds == null) return;
|
|
2840
|
+
assert(
|
|
2841
|
+
typeof config.heartbeatRefreshSeconds === "number" && config.heartbeatRefreshSeconds > 0,
|
|
2842
|
+
"heartbeatRefreshSeconds must be a number > 0"
|
|
2843
|
+
);
|
|
2844
|
+
}
|
|
2786
2845
|
function applyPollingInterval(config) {
|
|
2787
2846
|
assert(
|
|
2788
2847
|
!("pollingIntervalSeconds" in config) || config.pollingIntervalSeconds >= POLICY.MIN_POLLING_INTERVAL_MS / 1e3,
|
|
@@ -3478,10 +3537,190 @@ function getAll(schema) {
|
|
|
3478
3537
|
`DROP INDEX ${schema}.warning_i1`,
|
|
3479
3538
|
`DROP TABLE ${schema}.warning`
|
|
3480
3539
|
]
|
|
3540
|
+
},
|
|
3541
|
+
{
|
|
3542
|
+
release: "12.12.0",
|
|
3543
|
+
version: 30,
|
|
3544
|
+
previous: 29,
|
|
3545
|
+
install: [
|
|
3546
|
+
`ALTER TABLE ${schema}.job ADD COLUMN heartbeat_on timestamp with time zone`,
|
|
3547
|
+
`ALTER TABLE ${schema}.job ADD COLUMN heartbeat_seconds int`,
|
|
3548
|
+
`ALTER TABLE ${schema}.queue ADD COLUMN heartbeat_seconds int`,
|
|
3549
|
+
`
|
|
3550
|
+
CREATE OR REPLACE FUNCTION ${schema}.create_queue(queue_name text, options jsonb)
|
|
3551
|
+
RETURNS VOID AS
|
|
3552
|
+
$$
|
|
3553
|
+
DECLARE
|
|
3554
|
+
tablename varchar := CASE WHEN options->>'partition' = 'true'
|
|
3555
|
+
THEN 'j' || encode(sha224(queue_name::bytea), 'hex')
|
|
3556
|
+
ELSE 'job_common'
|
|
3557
|
+
END;
|
|
3558
|
+
queue_created_on timestamptz;
|
|
3559
|
+
BEGIN
|
|
3560
|
+
|
|
3561
|
+
WITH q as (
|
|
3562
|
+
INSERT INTO ${schema}.queue (
|
|
3563
|
+
name,
|
|
3564
|
+
policy,
|
|
3565
|
+
retry_limit,
|
|
3566
|
+
retry_delay,
|
|
3567
|
+
retry_backoff,
|
|
3568
|
+
retry_delay_max,
|
|
3569
|
+
expire_seconds,
|
|
3570
|
+
retention_seconds,
|
|
3571
|
+
deletion_seconds,
|
|
3572
|
+
warning_queued,
|
|
3573
|
+
dead_letter,
|
|
3574
|
+
partition,
|
|
3575
|
+
table_name,
|
|
3576
|
+
heartbeat_seconds
|
|
3577
|
+
)
|
|
3578
|
+
VALUES (
|
|
3579
|
+
queue_name,
|
|
3580
|
+
options->>'policy',
|
|
3581
|
+
COALESCE((options->>'retryLimit')::int, 2),
|
|
3582
|
+
COALESCE((options->>'retryDelay')::int, 0),
|
|
3583
|
+
COALESCE((options->>'retryBackoff')::bool, false),
|
|
3584
|
+
(options->>'retryDelayMax')::int,
|
|
3585
|
+
COALESCE((options->>'expireInSeconds')::int, 900),
|
|
3586
|
+
COALESCE((options->>'retentionSeconds')::int, 1209600),
|
|
3587
|
+
COALESCE((options->>'deleteAfterSeconds')::int, 604800),
|
|
3588
|
+
COALESCE((options->>'warningQueueSize')::int, 0),
|
|
3589
|
+
options->>'deadLetter',
|
|
3590
|
+
COALESCE((options->>'partition')::bool, false),
|
|
3591
|
+
tablename,
|
|
3592
|
+
(options->>'heartbeatSeconds')::int
|
|
3593
|
+
)
|
|
3594
|
+
ON CONFLICT DO NOTHING
|
|
3595
|
+
RETURNING created_on
|
|
3596
|
+
)
|
|
3597
|
+
SELECT created_on into queue_created_on from q;
|
|
3598
|
+
|
|
3599
|
+
IF queue_created_on IS NULL OR options->>'partition' IS DISTINCT FROM 'true' THEN
|
|
3600
|
+
RETURN;
|
|
3601
|
+
END IF;
|
|
3602
|
+
|
|
3603
|
+
EXECUTE format('CREATE TABLE ${schema}.%I (LIKE ${schema}.job INCLUDING DEFAULTS)', tablename);
|
|
3604
|
+
|
|
3605
|
+
EXECUTE ${schema}.job_table_format($cmd$ALTER TABLE ${schema}.job ADD PRIMARY KEY (name, id)$cmd$, tablename);
|
|
3606
|
+
EXECUTE ${schema}.job_table_format($cmd$ALTER TABLE ${schema}.job ADD CONSTRAINT q_fkey FOREIGN KEY (name) REFERENCES ${schema}.queue (name) ON DELETE RESTRICT DEFERRABLE INITIALLY DEFERRED$cmd$, tablename);
|
|
3607
|
+
EXECUTE ${schema}.job_table_format($cmd$ALTER TABLE ${schema}.job ADD CONSTRAINT dlq_fkey FOREIGN KEY (dead_letter) REFERENCES ${schema}.queue (name) ON DELETE RESTRICT DEFERRABLE INITIALLY DEFERRED$cmd$, tablename);
|
|
3608
|
+
|
|
3609
|
+
EXECUTE ${schema}.job_table_format($cmd$CREATE INDEX job_i5 ON ${schema}.job (name, start_after) INCLUDE (priority, created_on, id) WHERE state < 'active'$cmd$, tablename);
|
|
3610
|
+
EXECUTE ${schema}.job_table_format($cmd$CREATE UNIQUE INDEX job_i4 ON ${schema}.job (name, singleton_on, COALESCE(singleton_key, '')) WHERE state <> 'cancelled' AND singleton_on IS NOT NULL$cmd$, tablename);
|
|
3611
|
+
EXECUTE ${schema}.job_table_format($cmd$CREATE INDEX job_i7 ON ${schema}.job (name, group_id) WHERE state = 'active' AND group_id IS NOT NULL$cmd$, tablename);
|
|
3612
|
+
|
|
3613
|
+
IF options->>'policy' = 'short' THEN
|
|
3614
|
+
EXECUTE ${schema}.job_table_format($cmd$CREATE UNIQUE INDEX job_i1 ON ${schema}.job (name, COALESCE(singleton_key, '')) WHERE state = 'created' AND policy = 'short'$cmd$, tablename);
|
|
3615
|
+
ELSIF options->>'policy' = 'singleton' THEN
|
|
3616
|
+
EXECUTE ${schema}.job_table_format($cmd$CREATE UNIQUE INDEX job_i2 ON ${schema}.job (name, COALESCE(singleton_key, '')) WHERE state = 'active' AND policy = 'singleton'$cmd$, tablename);
|
|
3617
|
+
ELSIF options->>'policy' = 'stately' THEN
|
|
3618
|
+
EXECUTE ${schema}.job_table_format($cmd$CREATE UNIQUE INDEX job_i3 ON ${schema}.job (name, state, COALESCE(singleton_key, '')) WHERE state <= 'active' AND policy = 'stately'$cmd$, tablename);
|
|
3619
|
+
ELSIF options->>'policy' = 'exclusive' THEN
|
|
3620
|
+
EXECUTE ${schema}.job_table_format($cmd$CREATE UNIQUE INDEX job_i6 ON ${schema}.job (name, COALESCE(singleton_key, '')) WHERE state <= 'active' AND policy = 'exclusive'$cmd$, tablename);
|
|
3621
|
+
ELSIF options->>'policy' = 'key_strict_fifo' THEN
|
|
3622
|
+
EXECUTE ${schema}.job_table_format($cmd$CREATE UNIQUE INDEX job_i8 ON ${schema}.job (name, singleton_key) WHERE state IN ('active', 'retry', 'failed') AND policy = 'key_strict_fifo'$cmd$, tablename);
|
|
3623
|
+
EXECUTE ${schema}.job_table_format($cmd$ALTER TABLE ${schema}.job ADD CONSTRAINT job_key_strict_fifo_singleton_key_check CHECK (NOT (policy = 'key_strict_fifo' AND singleton_key IS NULL))$cmd$, tablename);
|
|
3624
|
+
END IF;
|
|
3625
|
+
|
|
3626
|
+
EXECUTE format('ALTER TABLE ${schema}.%I ADD CONSTRAINT cjc CHECK (name=%L)', tablename, queue_name);
|
|
3627
|
+
EXECUTE format('ALTER TABLE ${schema}.job ATTACH PARTITION ${schema}.%I FOR VALUES IN (%L)', tablename, queue_name);
|
|
3628
|
+
END;
|
|
3629
|
+
$$
|
|
3630
|
+
LANGUAGE plpgsql;
|
|
3631
|
+
`
|
|
3632
|
+
],
|
|
3633
|
+
uninstall: [
|
|
3634
|
+
// Restore previous version of create_queue function (without heartbeat_seconds)
|
|
3635
|
+
`
|
|
3636
|
+
CREATE OR REPLACE FUNCTION ${schema}.create_queue(queue_name text, options jsonb)
|
|
3637
|
+
RETURNS VOID AS
|
|
3638
|
+
$$
|
|
3639
|
+
DECLARE
|
|
3640
|
+
tablename varchar := CASE WHEN options->>'partition' = 'true'
|
|
3641
|
+
THEN 'j' || encode(sha224(queue_name::bytea), 'hex')
|
|
3642
|
+
ELSE 'job_common'
|
|
3643
|
+
END;
|
|
3644
|
+
queue_created_on timestamptz;
|
|
3645
|
+
BEGIN
|
|
3646
|
+
|
|
3647
|
+
WITH q as (
|
|
3648
|
+
INSERT INTO ${schema}.queue (
|
|
3649
|
+
name,
|
|
3650
|
+
policy,
|
|
3651
|
+
retry_limit,
|
|
3652
|
+
retry_delay,
|
|
3653
|
+
retry_backoff,
|
|
3654
|
+
retry_delay_max,
|
|
3655
|
+
expire_seconds,
|
|
3656
|
+
retention_seconds,
|
|
3657
|
+
deletion_seconds,
|
|
3658
|
+
warning_queued,
|
|
3659
|
+
dead_letter,
|
|
3660
|
+
partition,
|
|
3661
|
+
table_name
|
|
3662
|
+
)
|
|
3663
|
+
VALUES (
|
|
3664
|
+
queue_name,
|
|
3665
|
+
options->>'policy',
|
|
3666
|
+
COALESCE((options->>'retryLimit')::int, 2),
|
|
3667
|
+
COALESCE((options->>'retryDelay')::int, 0),
|
|
3668
|
+
COALESCE((options->>'retryBackoff')::bool, false),
|
|
3669
|
+
(options->>'retryDelayMax')::int,
|
|
3670
|
+
COALESCE((options->>'expireInSeconds')::int, 900),
|
|
3671
|
+
COALESCE((options->>'retentionSeconds')::int, 1209600),
|
|
3672
|
+
COALESCE((options->>'deleteAfterSeconds')::int, 604800),
|
|
3673
|
+
COALESCE((options->>'warningQueueSize')::int, 0),
|
|
3674
|
+
options->>'deadLetter',
|
|
3675
|
+
COALESCE((options->>'partition')::bool, false),
|
|
3676
|
+
tablename
|
|
3677
|
+
)
|
|
3678
|
+
ON CONFLICT DO NOTHING
|
|
3679
|
+
RETURNING created_on
|
|
3680
|
+
)
|
|
3681
|
+
SELECT created_on into queue_created_on from q;
|
|
3682
|
+
|
|
3683
|
+
IF queue_created_on IS NULL OR options->>'partition' IS DISTINCT FROM 'true' THEN
|
|
3684
|
+
RETURN;
|
|
3685
|
+
END IF;
|
|
3686
|
+
|
|
3687
|
+
EXECUTE format('CREATE TABLE ${schema}.%I (LIKE ${schema}.job INCLUDING DEFAULTS)', tablename);
|
|
3688
|
+
|
|
3689
|
+
EXECUTE ${schema}.job_table_format($cmd$ALTER TABLE ${schema}.job ADD PRIMARY KEY (name, id)$cmd$, tablename);
|
|
3690
|
+
EXECUTE ${schema}.job_table_format($cmd$ALTER TABLE ${schema}.job ADD CONSTRAINT q_fkey FOREIGN KEY (name) REFERENCES ${schema}.queue (name) ON DELETE RESTRICT DEFERRABLE INITIALLY DEFERRED$cmd$, tablename);
|
|
3691
|
+
EXECUTE ${schema}.job_table_format($cmd$ALTER TABLE ${schema}.job ADD CONSTRAINT dlq_fkey FOREIGN KEY (dead_letter) REFERENCES ${schema}.queue (name) ON DELETE RESTRICT DEFERRABLE INITIALLY DEFERRED$cmd$, tablename);
|
|
3692
|
+
|
|
3693
|
+
EXECUTE ${schema}.job_table_format($cmd$CREATE INDEX job_i5 ON ${schema}.job (name, start_after) INCLUDE (priority, created_on, id) WHERE state < 'active'$cmd$, tablename);
|
|
3694
|
+
EXECUTE ${schema}.job_table_format($cmd$CREATE UNIQUE INDEX job_i4 ON ${schema}.job (name, singleton_on, COALESCE(singleton_key, '')) WHERE state <> 'cancelled' AND singleton_on IS NOT NULL$cmd$, tablename);
|
|
3695
|
+
EXECUTE ${schema}.job_table_format($cmd$CREATE INDEX job_i7 ON ${schema}.job (name, group_id) WHERE state = 'active' AND group_id IS NOT NULL$cmd$, tablename);
|
|
3696
|
+
|
|
3697
|
+
IF options->>'policy' = 'short' THEN
|
|
3698
|
+
EXECUTE ${schema}.job_table_format($cmd$CREATE UNIQUE INDEX job_i1 ON ${schema}.job (name, COALESCE(singleton_key, '')) WHERE state = 'created' AND policy = 'short'$cmd$, tablename);
|
|
3699
|
+
ELSIF options->>'policy' = 'singleton' THEN
|
|
3700
|
+
EXECUTE ${schema}.job_table_format($cmd$CREATE UNIQUE INDEX job_i2 ON ${schema}.job (name, COALESCE(singleton_key, '')) WHERE state = 'active' AND policy = 'singleton'$cmd$, tablename);
|
|
3701
|
+
ELSIF options->>'policy' = 'stately' THEN
|
|
3702
|
+
EXECUTE ${schema}.job_table_format($cmd$CREATE UNIQUE INDEX job_i3 ON ${schema}.job (name, state, COALESCE(singleton_key, '')) WHERE state <= 'active' AND policy = 'stately'$cmd$, tablename);
|
|
3703
|
+
ELSIF options->>'policy' = 'exclusive' THEN
|
|
3704
|
+
EXECUTE ${schema}.job_table_format($cmd$CREATE UNIQUE INDEX job_i6 ON ${schema}.job (name, COALESCE(singleton_key, '')) WHERE state <= 'active' AND policy = 'exclusive'$cmd$, tablename);
|
|
3705
|
+
ELSIF options->>'policy' = 'key_strict_fifo' THEN
|
|
3706
|
+
EXECUTE ${schema}.job_table_format($cmd$CREATE UNIQUE INDEX job_i8 ON ${schema}.job (name, singleton_key) WHERE state IN ('active', 'retry', 'failed') AND policy = 'key_strict_fifo'$cmd$, tablename);
|
|
3707
|
+
EXECUTE ${schema}.job_table_format($cmd$ALTER TABLE ${schema}.job ADD CONSTRAINT job_key_strict_fifo_singleton_key_check CHECK (NOT (policy = 'key_strict_fifo' AND singleton_key IS NULL))$cmd$, tablename);
|
|
3708
|
+
END IF;
|
|
3709
|
+
|
|
3710
|
+
EXECUTE format('ALTER TABLE ${schema}.%I ADD CONSTRAINT cjc CHECK (name=%L)', tablename, queue_name);
|
|
3711
|
+
EXECUTE format('ALTER TABLE ${schema}.job ATTACH PARTITION ${schema}.%I FOR VALUES IN (%L)', tablename, queue_name);
|
|
3712
|
+
END;
|
|
3713
|
+
$$
|
|
3714
|
+
LANGUAGE plpgsql;
|
|
3715
|
+
`,
|
|
3716
|
+
`ALTER TABLE ${schema}.queue DROP COLUMN heartbeat_seconds`,
|
|
3717
|
+
`ALTER TABLE ${schema}.job DROP COLUMN heartbeat_seconds`,
|
|
3718
|
+
`ALTER TABLE ${schema}.job DROP COLUMN heartbeat_on`
|
|
3719
|
+
]
|
|
3481
3720
|
}
|
|
3482
3721
|
];
|
|
3483
3722
|
}
|
|
3484
|
-
const pgboss = { "schema":
|
|
3723
|
+
const pgboss = { "schema": 30 };
|
|
3485
3724
|
const packageJson = {
|
|
3486
3725
|
pgboss
|
|
3487
3726
|
};
|
|
@@ -4098,9 +4337,10 @@ class Manager extends EventEmitter {
|
|
|
4098
4337
|
}
|
|
4099
4338
|
}
|
|
4100
4339
|
}
|
|
4101
|
-
async #processJobs(name, jobs2, callback, worker) {
|
|
4340
|
+
async #processJobs(name, jobs2, callback, worker, heartbeatRefreshSeconds) {
|
|
4102
4341
|
const jobIds = jobs2.map((job) => job.id);
|
|
4103
4342
|
const maxExpiration = jobs2.reduce((acc, i) => Math.max(acc, i.expireInSeconds), 0);
|
|
4343
|
+
const heartbeatSeconds = jobs2.reduce((acc, j) => Math.max(acc, j.heartbeatSeconds || 0), 0);
|
|
4104
4344
|
const ac = new AbortController();
|
|
4105
4345
|
jobs2.forEach((job) => {
|
|
4106
4346
|
job.signal = ac.signal;
|
|
@@ -4108,6 +4348,18 @@ class Manager extends EventEmitter {
|
|
|
4108
4348
|
if (worker) {
|
|
4109
4349
|
worker.abortController = ac;
|
|
4110
4350
|
}
|
|
4351
|
+
let heartbeatTimer = null;
|
|
4352
|
+
if (heartbeatSeconds > 0) {
|
|
4353
|
+
const refreshSeconds = heartbeatRefreshSeconds ?? heartbeatSeconds / 2;
|
|
4354
|
+
const intervalMs = refreshSeconds * 1e3;
|
|
4355
|
+
heartbeatTimer = setInterval(async () => {
|
|
4356
|
+
try {
|
|
4357
|
+
await this.touch(name, jobIds);
|
|
4358
|
+
} catch (err) {
|
|
4359
|
+
this.emit(events$3.error, err);
|
|
4360
|
+
}
|
|
4361
|
+
}, intervalMs);
|
|
4362
|
+
}
|
|
4111
4363
|
try {
|
|
4112
4364
|
const result = await resolveWithinSeconds(callback(jobs2), maxExpiration, `handler execution exceeded ${maxExpiration}s`, ac);
|
|
4113
4365
|
await this.complete(name, jobIds, jobIds.length === 1 ? result : void 0);
|
|
@@ -4116,6 +4368,7 @@ class Manager extends EventEmitter {
|
|
|
4116
4368
|
await this.fail(name, jobIds, err);
|
|
4117
4369
|
this.#trackJobsFailed(name, jobs2, err);
|
|
4118
4370
|
} finally {
|
|
4371
|
+
if (heartbeatTimer) clearInterval(heartbeatTimer);
|
|
4119
4372
|
if (worker) {
|
|
4120
4373
|
worker.abortController = null;
|
|
4121
4374
|
}
|
|
@@ -4182,7 +4435,8 @@ class Manager extends EventEmitter {
|
|
|
4182
4435
|
localConcurrency = 1,
|
|
4183
4436
|
localGroupConcurrency,
|
|
4184
4437
|
groupConcurrency,
|
|
4185
|
-
orderByCreatedOn = true
|
|
4438
|
+
orderByCreatedOn = true,
|
|
4439
|
+
heartbeatRefreshSeconds
|
|
4186
4440
|
} = options;
|
|
4187
4441
|
if (localGroupConcurrency != null) {
|
|
4188
4442
|
this.#storeLocalGroupConfig(name, localGroupConcurrency);
|
|
@@ -4200,7 +4454,7 @@ class Manager extends EventEmitter {
|
|
|
4200
4454
|
this.#trackJobsActive(name, jobs2);
|
|
4201
4455
|
const worker = this.workers.get(workerId);
|
|
4202
4456
|
if (localGroupConcurrency == null) {
|
|
4203
|
-
await this.#processJobs(name, jobs2, callback, worker);
|
|
4457
|
+
await this.#processJobs(name, jobs2, callback, worker, heartbeatRefreshSeconds);
|
|
4204
4458
|
} else {
|
|
4205
4459
|
const { allowed, excess, groupedJobs } = this.#trackLocalGroupStart(name, jobs2);
|
|
4206
4460
|
if (excess.length > 0) {
|
|
@@ -4209,7 +4463,7 @@ class Manager extends EventEmitter {
|
|
|
4209
4463
|
}
|
|
4210
4464
|
if (allowed.length > 0) {
|
|
4211
4465
|
try {
|
|
4212
|
-
await this.#processJobs(name, allowed, callback, worker);
|
|
4466
|
+
await this.#processJobs(name, allowed, callback, worker, heartbeatRefreshSeconds);
|
|
4213
4467
|
} finally {
|
|
4214
4468
|
this.#trackLocalGroupEnd(name, groupedJobs);
|
|
4215
4469
|
}
|
|
@@ -4346,6 +4600,7 @@ class Manager extends EventEmitter {
|
|
|
4346
4600
|
retryDelay,
|
|
4347
4601
|
retryBackoff,
|
|
4348
4602
|
retryDelayMax,
|
|
4603
|
+
heartbeatSeconds,
|
|
4349
4604
|
group,
|
|
4350
4605
|
deadLetter = null
|
|
4351
4606
|
} = options;
|
|
@@ -4368,6 +4623,7 @@ class Manager extends EventEmitter {
|
|
|
4368
4623
|
retryDelay,
|
|
4369
4624
|
retryBackoff,
|
|
4370
4625
|
retryDelayMax,
|
|
4626
|
+
heartbeatSeconds,
|
|
4371
4627
|
deadLetter
|
|
4372
4628
|
};
|
|
4373
4629
|
const db = wrapper || this.db;
|
|
@@ -4543,6 +4799,15 @@ class Manager extends EventEmitter {
|
|
|
4543
4799
|
const result = await db.executeSql(sql, [name, ids]);
|
|
4544
4800
|
return this.mapCommandResponse(ids, result);
|
|
4545
4801
|
}
|
|
4802
|
+
async touch(name, id, options = {}) {
|
|
4803
|
+
assertQueueName(name);
|
|
4804
|
+
const db = this.assertDb(options);
|
|
4805
|
+
const ids = this.mapCompletionIdArg(id, "touch");
|
|
4806
|
+
const { table } = await this.getQueueCache(name);
|
|
4807
|
+
const sql = touchJobs(this.config.schema, table);
|
|
4808
|
+
const result = await db.executeSql(sql, [name, ids]);
|
|
4809
|
+
return this.mapCommandResponse(ids, result);
|
|
4810
|
+
}
|
|
4546
4811
|
async createQueue(name, options = {}) {
|
|
4547
4812
|
name = name || options.name;
|
|
4548
4813
|
assertQueueName(name);
|
|
@@ -4756,21 +5021,10 @@ class Boss extends EventEmitter {
|
|
|
4756
5021
|
errorEvent: events$2.error
|
|
4757
5022
|
};
|
|
4758
5023
|
}
|
|
4759
|
-
async #executeSql(sql) {
|
|
4760
|
-
const started = Date.now();
|
|
4761
|
-
const result = unwrapSQLResult(await this.#db.executeSql(sql));
|
|
4762
|
-
const elapsed = (Date.now() - started) / 1e3;
|
|
4763
|
-
if (elapsed > WARNINGS.SLOW_QUERY.seconds || this.#config.__test__warn_slow_query) {
|
|
4764
|
-
await emitAndPersistWarning(
|
|
4765
|
-
this.#warningContext,
|
|
4766
|
-
WARNING_TYPES.SLOW_QUERY,
|
|
4767
|
-
WARNINGS.SLOW_QUERY.message,
|
|
4768
|
-
{ elapsed, sql }
|
|
4769
|
-
);
|
|
4770
|
-
}
|
|
4771
|
-
return result;
|
|
4772
|
-
}
|
|
4773
5024
|
async #executeQuery(query2) {
|
|
5025
|
+
if (typeof query2 === "string") {
|
|
5026
|
+
query2 = { text: query2, values: [] };
|
|
5027
|
+
}
|
|
4774
5028
|
const started = Date.now();
|
|
4775
5029
|
const result = unwrapSQLResult(await this.#db.executeSql(query2.text, query2.values));
|
|
4776
5030
|
const elapsed = (Date.now() - started) / 1e3;
|
|
@@ -4806,7 +5060,7 @@ class Boss extends EventEmitter {
|
|
|
4806
5060
|
return;
|
|
4807
5061
|
}
|
|
4808
5062
|
const sql = deleteOldWarnings(this.#config.schema, this.#config.warningRetentionDays);
|
|
4809
|
-
await this.#
|
|
5063
|
+
await this.#executeQuery(sql);
|
|
4810
5064
|
}
|
|
4811
5065
|
async supervise(value) {
|
|
4812
5066
|
let queues;
|
|
@@ -4821,6 +5075,9 @@ class Boss extends EventEmitter {
|
|
|
4821
5075
|
acc[table].queues.push(q);
|
|
4822
5076
|
return acc;
|
|
4823
5077
|
}, {});
|
|
5078
|
+
const heartbeatQueueNames = new Set(
|
|
5079
|
+
queues.filter((q) => q.heartbeatSeconds != null).map((q) => q.name)
|
|
5080
|
+
);
|
|
4824
5081
|
for (const queueGroup of Object.values(queueGroups)) {
|
|
4825
5082
|
if (this.#stopping) return;
|
|
4826
5083
|
const { table, queues: queues2 } = queueGroup;
|
|
@@ -4828,12 +5085,12 @@ class Boss extends EventEmitter {
|
|
|
4828
5085
|
while (names.length) {
|
|
4829
5086
|
if (this.#stopping) return;
|
|
4830
5087
|
const chunk = names.splice(0, 100);
|
|
4831
|
-
await this.#monitor(table, chunk);
|
|
5088
|
+
await this.#monitor(table, chunk, heartbeatQueueNames);
|
|
4832
5089
|
await this.#maintain(table, chunk);
|
|
4833
5090
|
}
|
|
4834
5091
|
}
|
|
4835
5092
|
}
|
|
4836
|
-
async #monitor(table, names) {
|
|
5093
|
+
async #monitor(table, names, heartbeatQueueNames) {
|
|
4837
5094
|
if (this.#stopping) return;
|
|
4838
5095
|
const command = trySetQueueMonitorTime(
|
|
4839
5096
|
this.#config.schema,
|
|
@@ -4845,7 +5102,7 @@ class Boss extends EventEmitter {
|
|
|
4845
5102
|
if (rows.length) {
|
|
4846
5103
|
const queues = rows.map((q) => q.name);
|
|
4847
5104
|
const cacheStatsSql = cacheQueueStats(this.#config.schema, table, queues);
|
|
4848
|
-
const { rows: rowsCacheStats } = await this.#
|
|
5105
|
+
const { rows: rowsCacheStats } = await this.#executeQuery(cacheStatsSql);
|
|
4849
5106
|
if (this.#stopping) return;
|
|
4850
5107
|
const warnings2 = rowsCacheStats.filter((i) => i.queuedCount > (i.warningQueueSize || WARNINGS.LARGE_QUEUE.size));
|
|
4851
5108
|
for (const warning of warnings2) {
|
|
@@ -4857,7 +5114,13 @@ class Boss extends EventEmitter {
|
|
|
4857
5114
|
);
|
|
4858
5115
|
}
|
|
4859
5116
|
const sql = failJobsByTimeout(this.#config.schema, table, queues);
|
|
4860
|
-
await this.#
|
|
5117
|
+
await this.#executeQuery(sql);
|
|
5118
|
+
if (this.#stopping) return;
|
|
5119
|
+
const heartbeatQueues = queues.filter((q) => heartbeatQueueNames.has(q));
|
|
5120
|
+
if (heartbeatQueues.length) {
|
|
5121
|
+
const heartbeatSql = failJobsByHeartbeat(this.#config.schema, table, heartbeatQueues);
|
|
5122
|
+
await this.#executeQuery(heartbeatSql);
|
|
5123
|
+
}
|
|
4861
5124
|
}
|
|
4862
5125
|
}
|
|
4863
5126
|
async #maintain(table, names) {
|
|
@@ -4872,7 +5135,7 @@ class Boss extends EventEmitter {
|
|
|
4872
5135
|
if (rows.length) {
|
|
4873
5136
|
const queues = rows.map((q) => q.name);
|
|
4874
5137
|
const sql = deletion(this.#config.schema, table, queues);
|
|
4875
|
-
await this.#
|
|
5138
|
+
await this.#executeQuery(sql);
|
|
4876
5139
|
}
|
|
4877
5140
|
}
|
|
4878
5141
|
}
|
|
@@ -5187,6 +5450,9 @@ class PgBoss extends EventEmitter {
|
|
|
5187
5450
|
fail(name, id, data, options) {
|
|
5188
5451
|
return this.#manager.fail(name, id, data, options);
|
|
5189
5452
|
}
|
|
5453
|
+
touch(name, id, options) {
|
|
5454
|
+
return this.#manager.touch(name, id, options);
|
|
5455
|
+
}
|
|
5190
5456
|
/**
|
|
5191
5457
|
* @deprecated Use findJobs() instead
|
|
5192
5458
|
*/
|
|
@@ -9559,10 +9825,10 @@ const route11 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.definePrope
|
|
|
9559
9825
|
default: warnings,
|
|
9560
9826
|
loader
|
|
9561
9827
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
9562
|
-
const serverManifest = { "entry": { "module": "/assets/entry.client-
|
|
9828
|
+
const serverManifest = { "entry": { "module": "/assets/entry.client-Szv-xmaE.js", "imports": ["/assets/chunk-LFPYN7LY-Cj1DJmJR.js", "/assets/index-x2yWco1W.js"], "css": [] }, "routes": { "root": { "id": "root", "parentId": void 0, "path": "", "index": void 0, "caseSensitive": void 0, "hasAction": false, "hasLoader": true, "hasClientAction": false, "hasClientLoader": false, "hasClientMiddleware": false, "hasDefaultExport": true, "hasErrorBoundary": true, "module": "/assets/root-D0qqtdF7.js", "imports": ["/assets/chunk-LFPYN7LY-Cj1DJmJR.js", "/assets/index-x2yWco1W.js", "/assets/db-link-DmvfwdX4.js", "/assets/createLucideIcon-B0YqJFaz.js", "/assets/MenuTrigger-CEHCnGow.js", "/assets/useOpenInteractionType-Ss_6xZdw.js"], "css": ["/assets/root-Bpb4WtY4.css"], "clientActionModule": void 0, "clientLoaderModule": void 0, "clientMiddlewareModule": void 0, "hydrateFallbackModule": void 0 }, "routes/_index": { "id": "routes/_index", "parentId": "root", "path": void 0, "index": true, "caseSensitive": void 0, "hasAction": false, "hasLoader": true, "hasClientAction": false, "hasClientLoader": false, "hasClientMiddleware": false, "hasDefaultExport": true, "hasErrorBoundary": true, "module": "/assets/_index-9fLquIe1.js", "imports": ["/assets/chunk-LFPYN7LY-Cj1DJmJR.js", "/assets/db-link-DmvfwdX4.js", "/assets/button-Djse56Dx.js", "/assets/badge-B5ZugmiV.js", "/assets/table-CtSLyG7m.js", "/assets/error-card-CXoOCvsg.js"], "css": [], "clientActionModule": void 0, "clientLoaderModule": void 0, "clientMiddlewareModule": void 0, "hydrateFallbackModule": void 0 }, "routes/jobs": { "id": "routes/jobs", "parentId": "root", "path": "jobs", "index": void 0, "caseSensitive": void 0, "hasAction": false, "hasLoader": true, "hasClientAction": false, "hasClientLoader": false, "hasClientMiddleware": false, "hasDefaultExport": true, "hasErrorBoundary": true, "module": "/assets/jobs-CM6xcK-O.js", "imports": ["/assets/chunk-LFPYN7LY-Cj1DJmJR.js", "/assets/db-link-DmvfwdX4.js", "/assets/button-Djse56Dx.js", "/assets/badge-B5ZugmiV.js", "/assets/table-CtSLyG7m.js", "/assets/pagination-C4yyCmBA.js", "/assets/filter-select-DXyBBVm8.js", "/assets/error-card-CXoOCvsg.js"], "css": [], "clientActionModule": void 0, "clientLoaderModule": void 0, "clientMiddlewareModule": void 0, "hydrateFallbackModule": void 0 }, "routes/queues._index": { "id": "routes/queues._index", "parentId": "root", "path": "queues", "index": void 0, "caseSensitive": void 0, "hasAction": false, "hasLoader": true, "hasClientAction": false, "hasClientLoader": false, "hasClientMiddleware": false, "hasDefaultExport": true, "hasErrorBoundary": true, "module": "/assets/queues._index-Dn3ieC5d.js", "imports": ["/assets/chunk-LFPYN7LY-Cj1DJmJR.js", "/assets/db-link-DmvfwdX4.js", "/assets/button-Djse56Dx.js", "/assets/badge-B5ZugmiV.js", "/assets/filter-select-DXyBBVm8.js", "/assets/table-CtSLyG7m.js"], "css": [], "clientActionModule": void 0, "clientLoaderModule": void 0, "clientMiddlewareModule": void 0, "hydrateFallbackModule": void 0 }, "routes/queues.create": { "id": "routes/queues.create", "parentId": "root", "path": "queues/create", "index": void 0, "caseSensitive": void 0, "hasAction": true, "hasLoader": true, "hasClientAction": false, "hasClientLoader": false, "hasClientMiddleware": false, "hasDefaultExport": true, "hasErrorBoundary": true, "module": "/assets/queues.create-Ch3Mqw52.js", "imports": ["/assets/chunk-LFPYN7LY-Cj1DJmJR.js", "/assets/db-link-DmvfwdX4.js", "/assets/button-Djse56Dx.js", "/assets/chevron-down-B4tDL9Ah.js", "/assets/error-card-CXoOCvsg.js", "/assets/createLucideIcon-B0YqJFaz.js"], "css": [], "clientActionModule": void 0, "clientLoaderModule": void 0, "clientMiddlewareModule": void 0, "hydrateFallbackModule": void 0 }, "routes/queues.$name": { "id": "routes/queues.$name", "parentId": "root", "path": "queues/:name", "index": void 0, "caseSensitive": void 0, "hasAction": true, "hasLoader": true, "hasClientAction": false, "hasClientLoader": false, "hasClientMiddleware": false, "hasDefaultExport": true, "hasErrorBoundary": true, "module": "/assets/queues._name-GrviLLx2.js", "imports": ["/assets/chunk-LFPYN7LY-Cj1DJmJR.js", "/assets/db-link-DmvfwdX4.js", "/assets/button-Djse56Dx.js", "/assets/badge-B5ZugmiV.js", "/assets/table-CtSLyG7m.js", "/assets/pagination-C4yyCmBA.js", "/assets/filter-select-DXyBBVm8.js", "/assets/dialog-CQzw3QVH.js", "/assets/error-card-CXoOCvsg.js", "/assets/chevron-down-B4tDL9Ah.js", "/assets/createLucideIcon-B0YqJFaz.js", "/assets/MenuTrigger-CEHCnGow.js", "/assets/useOpenInteractionType-Ss_6xZdw.js", "/assets/index-x2yWco1W.js"], "css": [], "clientActionModule": void 0, "clientLoaderModule": void 0, "clientMiddlewareModule": void 0, "hydrateFallbackModule": void 0 }, "routes/queues.$name.jobs.$jobId": { "id": "routes/queues.$name.jobs.$jobId", "parentId": "root", "path": "queues/:name/jobs/:jobId", "index": void 0, "caseSensitive": void 0, "hasAction": true, "hasLoader": true, "hasClientAction": false, "hasClientLoader": false, "hasClientMiddleware": false, "hasDefaultExport": true, "hasErrorBoundary": true, "module": "/assets/queues._name.jobs._jobId-s_wYs79w.js", "imports": ["/assets/chunk-LFPYN7LY-Cj1DJmJR.js", "/assets/db-link-DmvfwdX4.js", "/assets/button-Djse56Dx.js", "/assets/badge-B5ZugmiV.js", "/assets/dialog-CQzw3QVH.js", "/assets/error-card-CXoOCvsg.js", "/assets/createLucideIcon-B0YqJFaz.js", "/assets/useOpenInteractionType-Ss_6xZdw.js", "/assets/index-x2yWco1W.js"], "css": [], "clientActionModule": void 0, "clientLoaderModule": void 0, "clientMiddlewareModule": void 0, "hydrateFallbackModule": void 0 }, "routes/schedules": { "id": "routes/schedules", "parentId": "root", "path": "schedules", "index": void 0, "caseSensitive": void 0, "hasAction": false, "hasLoader": true, "hasClientAction": false, "hasClientLoader": false, "hasClientMiddleware": false, "hasDefaultExport": true, "hasErrorBoundary": true, "module": "/assets/schedules-DwnuuhxF.js", "imports": ["/assets/chunk-LFPYN7LY-Cj1DJmJR.js", "/assets/db-link-DmvfwdX4.js", "/assets/button-Djse56Dx.js", "/assets/table-CtSLyG7m.js", "/assets/pagination-C4yyCmBA.js", "/assets/error-card-CXoOCvsg.js"], "css": [], "clientActionModule": void 0, "clientLoaderModule": void 0, "clientMiddlewareModule": void 0, "hydrateFallbackModule": void 0 }, "routes/schedules.$name.$key": { "id": "routes/schedules.$name.$key", "parentId": "root", "path": "schedules/:name/:key", "index": void 0, "caseSensitive": void 0, "hasAction": true, "hasLoader": true, "hasClientAction": false, "hasClientLoader": false, "hasClientMiddleware": false, "hasDefaultExport": true, "hasErrorBoundary": true, "module": "/assets/schedules._name._key-DJn-u3Cm.js", "imports": ["/assets/chunk-LFPYN7LY-Cj1DJmJR.js", "/assets/db-link-DmvfwdX4.js", "/assets/button-Djse56Dx.js", "/assets/dialog-CQzw3QVH.js", "/assets/error-card-CXoOCvsg.js", "/assets/createLucideIcon-B0YqJFaz.js", "/assets/useOpenInteractionType-Ss_6xZdw.js", "/assets/index-x2yWco1W.js"], "css": [], "clientActionModule": void 0, "clientLoaderModule": void 0, "clientMiddlewareModule": void 0, "hydrateFallbackModule": void 0 }, "routes/schedules.new": { "id": "routes/schedules.new", "parentId": "root", "path": "schedules/new", "index": void 0, "caseSensitive": void 0, "hasAction": true, "hasLoader": true, "hasClientAction": false, "hasClientLoader": false, "hasClientMiddleware": false, "hasDefaultExport": true, "hasErrorBoundary": true, "module": "/assets/schedules.new-CQuE2Uhz.js", "imports": ["/assets/chunk-LFPYN7LY-Cj1DJmJR.js", "/assets/db-link-DmvfwdX4.js", "/assets/button-Djse56Dx.js", "/assets/error-card-CXoOCvsg.js"], "css": [], "clientActionModule": void 0, "clientLoaderModule": void 0, "clientMiddlewareModule": void 0, "hydrateFallbackModule": void 0 }, "routes/send": { "id": "routes/send", "parentId": "root", "path": "send", "index": void 0, "caseSensitive": void 0, "hasAction": true, "hasLoader": true, "hasClientAction": false, "hasClientLoader": false, "hasClientMiddleware": false, "hasDefaultExport": true, "hasErrorBoundary": true, "module": "/assets/send-DVfuC6NR.js", "imports": ["/assets/chunk-LFPYN7LY-Cj1DJmJR.js", "/assets/db-link-DmvfwdX4.js", "/assets/button-Djse56Dx.js", "/assets/error-card-CXoOCvsg.js"], "css": [], "clientActionModule": void 0, "clientLoaderModule": void 0, "clientMiddlewareModule": void 0, "hydrateFallbackModule": void 0 }, "routes/warnings": { "id": "routes/warnings", "parentId": "root", "path": "warnings", "index": void 0, "caseSensitive": void 0, "hasAction": false, "hasLoader": true, "hasClientAction": false, "hasClientLoader": false, "hasClientMiddleware": false, "hasDefaultExport": true, "hasErrorBoundary": true, "module": "/assets/warnings-DqRQYomb.js", "imports": ["/assets/chunk-LFPYN7LY-Cj1DJmJR.js", "/assets/button-Djse56Dx.js", "/assets/badge-B5ZugmiV.js", "/assets/table-CtSLyG7m.js", "/assets/pagination-C4yyCmBA.js", "/assets/filter-select-DXyBBVm8.js", "/assets/error-card-CXoOCvsg.js", "/assets/db-link-DmvfwdX4.js"], "css": [], "clientActionModule": void 0, "clientLoaderModule": void 0, "clientMiddlewareModule": void 0, "hydrateFallbackModule": void 0 } }, "url": "/assets/manifest-acaa4b8e.js", "version": "acaa4b8e", "sri": void 0 };
|
|
9563
9829
|
const assetsBuildDirectory = "build/client";
|
|
9564
9830
|
const basename = "/";
|
|
9565
|
-
const future = { "unstable_optimizeDeps": false, "unstable_subResourceIntegrity": false, "unstable_trailingSlashAwareDataRequests": false, "v8_middleware": false, "v8_splitRouteModules": false, "v8_viteEnvironmentApi": false };
|
|
9831
|
+
const future = { "unstable_optimizeDeps": false, "unstable_subResourceIntegrity": false, "unstable_trailingSlashAwareDataRequests": false, "unstable_previewServerPrerendering": false, "v8_middleware": false, "v8_splitRouteModules": false, "v8_viteEnvironmentApi": false };
|
|
9566
9832
|
const ssr = true;
|
|
9567
9833
|
const isSpaMode = false;
|
|
9568
9834
|
const prerender = [];
|