deepline 0.3.114 → 0.3.116
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bundling-sources/sdk/src/release.ts +1 -1
- package/dist/bundling-sources/shared_libs/observability/dlq.ts +942 -0
- package/dist/bundling-sources/shared_libs/observability/queue-health.ts +91 -21
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres.ts +220 -5
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runtime-queue-health.ts +245 -81
- package/dist/bundling-sources/shared_libs/plays/share/static-pipeline-summary.ts +2 -2
- package/dist/cli/index.js +1 -1
- package/dist/cli/index.mjs +1 -1
- package/dist/index.js +1 -1
- package/dist/index.mjs +1 -1
- package/dist/install-integrity.json +1 -0
- package/dist/release.d.mts +1 -1
- package/dist/release.d.ts +1 -1
- package/dist/release.js +1 -1
- package/dist/release.mjs +1 -1
- package/package.json +1 -1
|
@@ -118,6 +118,15 @@ export const OPERATIONS_QUEUE_CATALOG = [
|
|
|
118
118
|
60_000,
|
|
119
119
|
180_000,
|
|
120
120
|
),
|
|
121
|
+
queue(
|
|
122
|
+
'compute-billing-jobs',
|
|
123
|
+
'Compute billing jobs',
|
|
124
|
+
'leased_workset',
|
|
125
|
+
'billing',
|
|
126
|
+
'Settle durable compute billing obligations after a runtime run ends',
|
|
127
|
+
300_000,
|
|
128
|
+
900_000,
|
|
129
|
+
),
|
|
121
130
|
queue(
|
|
122
131
|
'play-webhook-receipts',
|
|
123
132
|
'Play webhook receipts',
|
|
@@ -707,7 +716,10 @@ export type QueueHealthAttentionReason =
|
|
|
707
716
|
| 'backlog_count_inexact'
|
|
708
717
|
| 'backlog_age_unavailable';
|
|
709
718
|
export type QueueHealthCount = { value: number | null; exact: boolean };
|
|
710
|
-
export type QueueHealthCapacity = {
|
|
719
|
+
export type QueueHealthCapacity = {
|
|
720
|
+
active: number | null;
|
|
721
|
+
limit: number | null;
|
|
722
|
+
};
|
|
711
723
|
export type QueueHealthSnapshot = {
|
|
712
724
|
schemaVersion: typeof QUEUE_HEALTH_SCHEMA_VERSION;
|
|
713
725
|
queueId: string;
|
|
@@ -761,13 +773,16 @@ export function parseQueueHealthSnapshot(input: unknown): QueueHealthSnapshot {
|
|
|
761
773
|
if (record.schemaVersion !== 1)
|
|
762
774
|
throw new Error('Queue health schemaVersion must be 1.');
|
|
763
775
|
const layer = legacyString(record.layer, 'layer') as QueueHealthLayer;
|
|
764
|
-
if (!legacyLayers.has(layer))
|
|
776
|
+
if (!legacyLayers.has(layer))
|
|
777
|
+
throw new Error('Queue health layer is not supported.');
|
|
765
778
|
const availability = legacyString(
|
|
766
779
|
record.availability,
|
|
767
780
|
'availability',
|
|
768
781
|
) as QueueHealthAvailability;
|
|
769
782
|
if (availability !== 'available' && availability !== 'unavailable')
|
|
770
|
-
throw new Error(
|
|
783
|
+
throw new Error(
|
|
784
|
+
'Queue health availability must be available or unavailable.',
|
|
785
|
+
);
|
|
771
786
|
const freshness = legacyRecord(record.freshness, 'freshness');
|
|
772
787
|
const capacity = legacyRecord(record.capacity, 'capacity');
|
|
773
788
|
const thresholds = legacyRecord(record.thresholds, 'thresholds');
|
|
@@ -778,15 +793,26 @@ export function parseQueueHealthSnapshot(input: unknown): QueueHealthSnapshot {
|
|
|
778
793
|
layer,
|
|
779
794
|
transport: legacyIdentifier(record.transport, 'transport'),
|
|
780
795
|
observedAt: legacyNumber(record.observedAt, 'observedAt'),
|
|
781
|
-
freshness: {
|
|
796
|
+
freshness: {
|
|
797
|
+
staleAfterMs: legacyPositive(
|
|
798
|
+
freshness.staleAfterMs,
|
|
799
|
+
'freshness.staleAfterMs',
|
|
800
|
+
),
|
|
801
|
+
},
|
|
782
802
|
availability,
|
|
783
803
|
queued: legacyCount(record.queued, 'queued'),
|
|
784
804
|
running: legacyCount(record.running, 'running'),
|
|
785
805
|
retryWaiting: legacyCount(record.retryWaiting, 'retryWaiting'),
|
|
786
806
|
blocked: legacyCount(record.blocked, 'blocked'),
|
|
787
807
|
deadLetter: legacyCount(record.deadLetter, 'deadLetter'),
|
|
788
|
-
oldestQueuedAgeMs: legacyNullableNumber(
|
|
789
|
-
|
|
808
|
+
oldestQueuedAgeMs: legacyNullableNumber(
|
|
809
|
+
record.oldestQueuedAgeMs,
|
|
810
|
+
'oldestQueuedAgeMs',
|
|
811
|
+
),
|
|
812
|
+
oldestBlockedAgeMs: legacyNullableNumber(
|
|
813
|
+
record.oldestBlockedAgeMs,
|
|
814
|
+
'oldestBlockedAgeMs',
|
|
815
|
+
),
|
|
790
816
|
capacity: {
|
|
791
817
|
active: legacyNullableNumber(capacity.active, 'capacity.active'),
|
|
792
818
|
limit: legacyNullableNumber(capacity.limit, 'capacity.limit'),
|
|
@@ -802,10 +828,17 @@ export function parseQueueHealthSnapshot(input: unknown): QueueHealthSnapshot {
|
|
|
802
828
|
for (const name of legacyCountNames) {
|
|
803
829
|
const count = snapshot[name];
|
|
804
830
|
if (count.value !== null || count.exact)
|
|
805
|
-
throw new Error(
|
|
831
|
+
throw new Error(
|
|
832
|
+
`Queue health ${name} must be unknown when availability is unavailable.`,
|
|
833
|
+
);
|
|
806
834
|
}
|
|
807
|
-
if (
|
|
808
|
-
|
|
835
|
+
if (
|
|
836
|
+
snapshot.oldestQueuedAgeMs !== null ||
|
|
837
|
+
snapshot.oldestBlockedAgeMs !== null
|
|
838
|
+
)
|
|
839
|
+
throw new Error(
|
|
840
|
+
'Queue health oldestQueuedAgeMs must be null when availability is unavailable.',
|
|
841
|
+
);
|
|
809
842
|
}
|
|
810
843
|
if (
|
|
811
844
|
snapshot.queued.exact &&
|
|
@@ -814,7 +847,9 @@ export function parseQueueHealthSnapshot(input: unknown): QueueHealthSnapshot {
|
|
|
814
847
|
snapshot.retryWaiting.value === 0 &&
|
|
815
848
|
snapshot.oldestQueuedAgeMs !== null
|
|
816
849
|
) {
|
|
817
|
-
throw new Error(
|
|
850
|
+
throw new Error(
|
|
851
|
+
'Queue health oldestQueuedAgeMs requires queued or retry-waiting work.',
|
|
852
|
+
);
|
|
818
853
|
}
|
|
819
854
|
if (
|
|
820
855
|
snapshot.blocked.exact &&
|
|
@@ -823,7 +858,9 @@ export function parseQueueHealthSnapshot(input: unknown): QueueHealthSnapshot {
|
|
|
823
858
|
snapshot.deadLetter.value === 0 &&
|
|
824
859
|
snapshot.oldestBlockedAgeMs !== null
|
|
825
860
|
) {
|
|
826
|
-
throw new Error(
|
|
861
|
+
throw new Error(
|
|
862
|
+
'Queue health oldestBlockedAgeMs requires blocked or dead-letter work.',
|
|
863
|
+
);
|
|
827
864
|
}
|
|
828
865
|
return snapshot;
|
|
829
866
|
}
|
|
@@ -843,31 +880,57 @@ export function assessQueueHealth(
|
|
|
843
880
|
const freshness: QueueHealthFreshness =
|
|
844
881
|
observedAgeMs > snapshot.freshness.staleAfterMs ? 'stale' : 'fresh';
|
|
845
882
|
if (snapshot.availability === 'unavailable')
|
|
846
|
-
return {
|
|
883
|
+
return {
|
|
884
|
+
status: 'unknown',
|
|
885
|
+
freshness,
|
|
886
|
+
observedAgeMs,
|
|
887
|
+
attentionReasons: ['source_unavailable'],
|
|
888
|
+
};
|
|
847
889
|
if (freshness === 'stale')
|
|
848
|
-
return {
|
|
890
|
+
return {
|
|
891
|
+
status: 'unknown',
|
|
892
|
+
freshness,
|
|
893
|
+
observedAgeMs,
|
|
894
|
+
attentionReasons: ['snapshot_stale'],
|
|
895
|
+
};
|
|
849
896
|
const attentionReasons: QueueHealthAttentionReason[] = [];
|
|
850
897
|
if (knownItems(snapshot.blocked)) attentionReasons.push('blocked_work');
|
|
851
|
-
if (knownItems(snapshot.deadLetter))
|
|
898
|
+
if (knownItems(snapshot.deadLetter))
|
|
899
|
+
attentionReasons.push('dead_letter_work');
|
|
852
900
|
if (attentionReasons.length)
|
|
853
901
|
return { status: 'blocked', freshness, observedAgeMs, attentionReasons };
|
|
854
902
|
if (
|
|
855
903
|
snapshot.oldestQueuedAgeMs !== null &&
|
|
856
904
|
snapshot.oldestQueuedAgeMs >= snapshot.thresholds.degradedOldestQueuedAgeMs
|
|
857
905
|
)
|
|
858
|
-
return {
|
|
906
|
+
return {
|
|
907
|
+
status: 'degraded',
|
|
908
|
+
freshness,
|
|
909
|
+
observedAgeMs,
|
|
910
|
+
attentionReasons: ['backlog_aged'],
|
|
911
|
+
};
|
|
859
912
|
if (
|
|
860
913
|
!snapshot.queued.exact ||
|
|
861
914
|
!snapshot.retryWaiting.exact ||
|
|
862
915
|
!snapshot.blocked.exact ||
|
|
863
916
|
!snapshot.deadLetter.exact
|
|
864
917
|
)
|
|
865
|
-
return {
|
|
918
|
+
return {
|
|
919
|
+
status: 'unknown',
|
|
920
|
+
freshness,
|
|
921
|
+
observedAgeMs,
|
|
922
|
+
attentionReasons: ['backlog_count_inexact'],
|
|
923
|
+
};
|
|
866
924
|
if (
|
|
867
925
|
(knownItems(snapshot.queued) || knownItems(snapshot.retryWaiting)) &&
|
|
868
926
|
snapshot.oldestQueuedAgeMs === null
|
|
869
927
|
)
|
|
870
|
-
return {
|
|
928
|
+
return {
|
|
929
|
+
status: 'unknown',
|
|
930
|
+
freshness,
|
|
931
|
+
observedAgeMs,
|
|
932
|
+
attentionReasons: ['backlog_age_unavailable'],
|
|
933
|
+
};
|
|
871
934
|
return { status: 'healthy', freshness, observedAgeMs, attentionReasons: [] };
|
|
872
935
|
}
|
|
873
936
|
|
|
@@ -902,7 +965,8 @@ export function queueHealthTelemetryFields(
|
|
|
902
965
|
queueOldestBlockedAgeMs: snapshot.oldestBlockedAgeMs,
|
|
903
966
|
queueCapacityActive: snapshot.capacity.active,
|
|
904
967
|
queueCapacityLimit: snapshot.capacity.limit,
|
|
905
|
-
queueDegradedOldestQueuedAgeMs:
|
|
968
|
+
queueDegradedOldestQueuedAgeMs:
|
|
969
|
+
snapshot.thresholds.degradedOldestQueuedAgeMs,
|
|
906
970
|
queueAttentionReasons: assessment.attentionReasons,
|
|
907
971
|
};
|
|
908
972
|
}
|
|
@@ -933,12 +997,16 @@ function legacyString(value: unknown, label: string): string {
|
|
|
933
997
|
function legacyIdentifier(value: unknown, label: string): string {
|
|
934
998
|
const result = legacyString(value, label);
|
|
935
999
|
if (result.length > 96 || !/^[a-z][a-z0-9]*(?:[._-][a-z0-9]+)*$/.test(result))
|
|
936
|
-
throw new Error(
|
|
1000
|
+
throw new Error(
|
|
1001
|
+
`Queue health ${label} must be a stable low-cardinality identifier.`,
|
|
1002
|
+
);
|
|
937
1003
|
return result;
|
|
938
1004
|
}
|
|
939
1005
|
function legacyNumber(value: unknown, label: string): number {
|
|
940
1006
|
if (typeof value !== 'number' || !Number.isFinite(value) || value < 0)
|
|
941
|
-
throw new Error(
|
|
1007
|
+
throw new Error(
|
|
1008
|
+
`Queue health ${label} must be a finite non-negative number.`,
|
|
1009
|
+
);
|
|
942
1010
|
return value;
|
|
943
1011
|
}
|
|
944
1012
|
function legacyPositive(value: unknown, label: string): number {
|
|
@@ -955,7 +1023,9 @@ function legacyCount(value: unknown, label: string): QueueHealthCount {
|
|
|
955
1023
|
throw new Error(`Queue health ${label}.exact must be a boolean.`);
|
|
956
1024
|
const count = legacyNullableNumber(record.value, `${label}.value`);
|
|
957
1025
|
if (count === null && record.exact)
|
|
958
|
-
throw new Error(
|
|
1026
|
+
throw new Error(
|
|
1027
|
+
`Queue health ${label}.exact cannot be true when value is unknown.`,
|
|
1028
|
+
);
|
|
959
1029
|
return { value: count, exact: record.exact };
|
|
960
1030
|
}
|
|
961
1031
|
function knownItems(count: QueueHealthCount): boolean {
|
|
@@ -217,11 +217,12 @@ const POSTGRES_SCHEDULER_SCHEMA_INIT_STATEMENT_TIMEOUT_MS = 60_000;
|
|
|
217
217
|
* interrupted deployment cannot claim a newer version without its required
|
|
218
218
|
* objects.
|
|
219
219
|
*/
|
|
220
|
-
//
|
|
221
|
-
//
|
|
222
|
-
//
|
|
223
|
-
//
|
|
224
|
-
|
|
220
|
+
// v38 adds bounded health indexes for the runtime-owned outbox, sandbox
|
|
221
|
+
// cleanup, and compute-billing queues. The indexes are additive: v37 cron
|
|
222
|
+
// scheduling, admission, and outbox projection remain valid while a deploy
|
|
223
|
+
// expands the shared schema, then the marker records the completed health
|
|
224
|
+
// capability for deployment tooling.
|
|
225
|
+
export const POSTGRES_SCHEDULER_SCHEMA_VERSION = 38;
|
|
225
226
|
const POSTGRES_SCHEDULER_SCHEMA_MIGRATIONS_TABLE =
|
|
226
227
|
'scheduler_schema_migrations';
|
|
227
228
|
export const POSTGRES_SCHEDULER_OPEN_RECOVERY_INDEX =
|
|
@@ -1567,6 +1568,87 @@ export async function hasCurrentPostgresSchedulerSchemaShape(
|
|
|
1567
1568
|
AND index_row.indrelid = to_regclass($3)
|
|
1568
1569
|
AND index_row.indisready AND index_row.indisvalid
|
|
1569
1570
|
)
|
|
1571
|
+
AND EXISTS (
|
|
1572
|
+
SELECT 1 FROM pg_index AS index_row
|
|
1573
|
+
JOIN pg_class AS index_class ON index_class.oid = index_row.indexrelid
|
|
1574
|
+
JOIN pg_namespace AS index_namespace ON index_namespace.oid = index_class.relnamespace
|
|
1575
|
+
WHERE index_namespace.nspname = $1
|
|
1576
|
+
AND index_class.relname = 'runtime_scheduler_outbox_ready_health_idx'
|
|
1577
|
+
AND index_row.indrelid = to_regclass($3)
|
|
1578
|
+
AND index_row.indisready AND index_row.indisvalid
|
|
1579
|
+
)
|
|
1580
|
+
AND EXISTS (
|
|
1581
|
+
SELECT 1 FROM pg_index AS index_row
|
|
1582
|
+
JOIN pg_class AS index_class ON index_class.oid = index_row.indexrelid
|
|
1583
|
+
JOIN pg_namespace AS index_namespace ON index_namespace.oid = index_class.relnamespace
|
|
1584
|
+
WHERE index_namespace.nspname = $1
|
|
1585
|
+
AND index_class.relname = 'runtime_scheduler_outbox_dead_health_idx'
|
|
1586
|
+
AND index_row.indrelid = to_regclass($3)
|
|
1587
|
+
AND index_row.indisready AND index_row.indisvalid
|
|
1588
|
+
)
|
|
1589
|
+
AND EXISTS (
|
|
1590
|
+
SELECT 1 FROM pg_index AS index_row
|
|
1591
|
+
JOIN pg_class AS index_class ON index_class.oid = index_row.indexrelid
|
|
1592
|
+
JOIN pg_namespace AS index_namespace ON index_namespace.oid = index_class.relnamespace
|
|
1593
|
+
WHERE index_namespace.nspname = $1
|
|
1594
|
+
AND index_class.relname = 'runtime_scheduler_outbox_lease_health_idx'
|
|
1595
|
+
AND index_row.indrelid = to_regclass($3)
|
|
1596
|
+
AND index_row.indisready AND index_row.indisvalid
|
|
1597
|
+
)
|
|
1598
|
+
AND EXISTS (
|
|
1599
|
+
SELECT 1 FROM pg_index AS index_row
|
|
1600
|
+
JOIN pg_class AS index_class ON index_class.oid = index_row.indexrelid
|
|
1601
|
+
JOIN pg_namespace AS index_namespace ON index_namespace.oid = index_class.relnamespace
|
|
1602
|
+
WHERE index_namespace.nspname = $1
|
|
1603
|
+
AND index_class.relname = 'runtime_scheduler_sandbox_cleanup_v2_ready_health_idx'
|
|
1604
|
+
AND index_row.indrelid = to_regclass($7)
|
|
1605
|
+
AND index_row.indisready AND index_row.indisvalid
|
|
1606
|
+
)
|
|
1607
|
+
AND EXISTS (
|
|
1608
|
+
SELECT 1 FROM pg_index AS index_row
|
|
1609
|
+
JOIN pg_class AS index_class ON index_class.oid = index_row.indexrelid
|
|
1610
|
+
JOIN pg_namespace AS index_namespace ON index_namespace.oid = index_class.relnamespace
|
|
1611
|
+
WHERE index_namespace.nspname = $1
|
|
1612
|
+
AND index_class.relname = 'runtime_scheduler_sandbox_cleanup_v2_lease_health_idx'
|
|
1613
|
+
AND index_row.indrelid = to_regclass($7)
|
|
1614
|
+
AND index_row.indisready AND index_row.indisvalid
|
|
1615
|
+
)
|
|
1616
|
+
AND EXISTS (
|
|
1617
|
+
SELECT 1 FROM pg_index AS index_row
|
|
1618
|
+
JOIN pg_class AS index_class ON index_class.oid = index_row.indexrelid
|
|
1619
|
+
JOIN pg_namespace AS index_namespace ON index_namespace.oid = index_class.relnamespace
|
|
1620
|
+
WHERE index_namespace.nspname = $1
|
|
1621
|
+
AND index_class.relname = 'runtime_scheduler_compute_billing_ready_health_idx'
|
|
1622
|
+
AND index_row.indrelid = to_regclass($8)
|
|
1623
|
+
AND index_row.indisready AND index_row.indisvalid
|
|
1624
|
+
)
|
|
1625
|
+
AND EXISTS (
|
|
1626
|
+
SELECT 1 FROM pg_index AS index_row
|
|
1627
|
+
JOIN pg_class AS index_class ON index_class.oid = index_row.indexrelid
|
|
1628
|
+
JOIN pg_namespace AS index_namespace ON index_namespace.oid = index_class.relnamespace
|
|
1629
|
+
WHERE index_namespace.nspname = $1
|
|
1630
|
+
AND index_class.relname = 'runtime_scheduler_sandbox_cleanup_v2_blocked_health_idx'
|
|
1631
|
+
AND index_row.indrelid = to_regclass($7)
|
|
1632
|
+
AND index_row.indisready AND index_row.indisvalid
|
|
1633
|
+
)
|
|
1634
|
+
AND EXISTS (
|
|
1635
|
+
SELECT 1 FROM pg_index AS index_row
|
|
1636
|
+
JOIN pg_class AS index_class ON index_class.oid = index_row.indexrelid
|
|
1637
|
+
JOIN pg_namespace AS index_namespace ON index_namespace.oid = index_class.relnamespace
|
|
1638
|
+
WHERE index_namespace.nspname = $1
|
|
1639
|
+
AND index_class.relname = 'runtime_scheduler_compute_billing_lease_health_idx'
|
|
1640
|
+
AND index_row.indrelid = to_regclass($8)
|
|
1641
|
+
AND index_row.indisready AND index_row.indisvalid
|
|
1642
|
+
)
|
|
1643
|
+
AND EXISTS (
|
|
1644
|
+
SELECT 1 FROM pg_index AS index_row
|
|
1645
|
+
JOIN pg_class AS index_class ON index_class.oid = index_row.indexrelid
|
|
1646
|
+
JOIN pg_namespace AS index_namespace ON index_namespace.oid = index_class.relnamespace
|
|
1647
|
+
WHERE index_namespace.nspname = $1
|
|
1648
|
+
AND index_class.relname = 'runtime_scheduler_compute_billing_blocked_health_idx'
|
|
1649
|
+
AND index_row.indrelid = to_regclass($8)
|
|
1650
|
+
AND index_row.indisready AND index_row.indisvalid
|
|
1651
|
+
)
|
|
1570
1652
|
AND (
|
|
1571
1653
|
$5::boolean = false
|
|
1572
1654
|
OR EXISTS (
|
|
@@ -1608,6 +1690,8 @@ export async function hasCurrentPostgresSchedulerSchemaShape(
|
|
|
1608
1690
|
`${quotedSchema}.${quoteIdent('runs')}`,
|
|
1609
1691
|
requirements.deliveredOutboxRetentionIndex !== false,
|
|
1610
1692
|
requirements.blockedOutboxIndex !== false,
|
|
1693
|
+
`${quotedSchema}.${quoteIdent('sandbox_cleanup_jobs_v2')}`,
|
|
1694
|
+
`${quotedSchema}.${quoteIdent('compute_billing_jobs_v2')}`,
|
|
1611
1695
|
],
|
|
1612
1696
|
);
|
|
1613
1697
|
return runtimeAdminIndexes.rows[0]?.ready === true;
|
|
@@ -3134,6 +3218,30 @@ export async function ensurePostgresSchedulerSchema(
|
|
|
3134
3218
|
(available_at, created_at, provider, sandbox_id)
|
|
3135
3219
|
WHERE status <> 'deleted'
|
|
3136
3220
|
`);
|
|
3221
|
+
if (!options?.deferRuntimeAdminIndexes) {
|
|
3222
|
+
await client.query(`
|
|
3223
|
+
CREATE INDEX IF NOT EXISTS runtime_scheduler_sandbox_cleanup_v2_ready_health_idx
|
|
3224
|
+
ON ${tableName('sandbox_cleanup_jobs_v2', options)}
|
|
3225
|
+
(available_at, created_at, provider, sandbox_id)
|
|
3226
|
+
WHERE status <> 'deleted'
|
|
3227
|
+
AND blocked_at IS NULL
|
|
3228
|
+
AND lease_owner IS NULL
|
|
3229
|
+
AND status <> 'deleting'
|
|
3230
|
+
`);
|
|
3231
|
+
await client.query(`
|
|
3232
|
+
CREATE INDEX IF NOT EXISTS runtime_scheduler_sandbox_cleanup_v2_lease_health_idx
|
|
3233
|
+
ON ${tableName('sandbox_cleanup_jobs_v2', options)}
|
|
3234
|
+
(lease_expires_at, created_at, provider, sandbox_id)
|
|
3235
|
+
WHERE status <> 'deleted' AND lease_owner IS NOT NULL
|
|
3236
|
+
`);
|
|
3237
|
+
await client.query(`
|
|
3238
|
+
CREATE INDEX IF NOT EXISTS runtime_scheduler_sandbox_cleanup_v2_blocked_health_idx
|
|
3239
|
+
ON ${tableName('sandbox_cleanup_jobs_v2', options)}
|
|
3240
|
+
(blocked_at, lease_expires_at, created_at, provider, sandbox_id)
|
|
3241
|
+
WHERE status <> 'deleted'
|
|
3242
|
+
AND (blocked_at IS NOT NULL OR status = 'deleting')
|
|
3243
|
+
`);
|
|
3244
|
+
}
|
|
3137
3245
|
await client.query(`
|
|
3138
3246
|
CREATE INDEX IF NOT EXISTS ${POSTGRES_SCHEDULER_COMPUTE_BILLING_PENDING_INDEX}
|
|
3139
3247
|
ON ${tableName('compute_billing_jobs_v2', options)}
|
|
@@ -3187,6 +3295,27 @@ export async function ensurePostgresSchedulerSchema(
|
|
|
3187
3295
|
ON ${tableName('outbox', options)} (created_at, event_id)
|
|
3188
3296
|
WHERE delivered_at IS NULL AND failed_at IS NULL
|
|
3189
3297
|
`);
|
|
3298
|
+
await client.query(`
|
|
3299
|
+
CREATE INDEX IF NOT EXISTS runtime_scheduler_outbox_lease_health_idx
|
|
3300
|
+
ON ${tableName('outbox', options)}
|
|
3301
|
+
(lease_expires_at, created_at, event_id)
|
|
3302
|
+
WHERE delivered_at IS NULL
|
|
3303
|
+
AND failed_at IS NULL
|
|
3304
|
+
AND lease_owner IS NOT NULL
|
|
3305
|
+
`);
|
|
3306
|
+
await client.query(`
|
|
3307
|
+
CREATE INDEX IF NOT EXISTS runtime_scheduler_outbox_ready_health_idx
|
|
3308
|
+
ON ${tableName('outbox', options)}
|
|
3309
|
+
(coalesce(next_attempt_at, created_at), created_at, event_id)
|
|
3310
|
+
WHERE delivered_at IS NULL
|
|
3311
|
+
AND failed_at IS NULL
|
|
3312
|
+
AND lease_owner IS NULL
|
|
3313
|
+
`);
|
|
3314
|
+
await client.query(`
|
|
3315
|
+
CREATE INDEX IF NOT EXISTS runtime_scheduler_outbox_dead_health_idx
|
|
3316
|
+
ON ${tableName('outbox', options)} (failed_at, event_id)
|
|
3317
|
+
WHERE delivered_at IS NULL AND failed_at IS NOT NULL
|
|
3318
|
+
`);
|
|
3190
3319
|
await client.query(`
|
|
3191
3320
|
CREATE INDEX IF NOT EXISTS runtime_scheduler_outbox_delivered_retention_idx
|
|
3192
3321
|
ON ${tableName('outbox', options)} (delivered_at, event_id)
|
|
@@ -3198,6 +3327,28 @@ export async function ensurePostgresSchedulerSchema(
|
|
|
3198
3327
|
WHERE delivered_at IS NULL AND failed_at IS NOT NULL
|
|
3199
3328
|
`);
|
|
3200
3329
|
}
|
|
3330
|
+
if (!options?.deferRuntimeAdminIndexes) {
|
|
3331
|
+
await client.query(`
|
|
3332
|
+
CREATE INDEX IF NOT EXISTS runtime_scheduler_compute_billing_ready_health_idx
|
|
3333
|
+
ON ${tableName('compute_billing_jobs_v2', options)}
|
|
3334
|
+
(available_at, created_at, run_id)
|
|
3335
|
+
WHERE status <> 'settled'
|
|
3336
|
+
AND blocked_at IS NULL
|
|
3337
|
+
AND lease_owner IS NULL
|
|
3338
|
+
`);
|
|
3339
|
+
await client.query(`
|
|
3340
|
+
CREATE INDEX IF NOT EXISTS runtime_scheduler_compute_billing_lease_health_idx
|
|
3341
|
+
ON ${tableName('compute_billing_jobs_v2', options)}
|
|
3342
|
+
(lease_expires_at, created_at, run_id)
|
|
3343
|
+
WHERE status <> 'settled' AND lease_owner IS NOT NULL
|
|
3344
|
+
`);
|
|
3345
|
+
await client.query(`
|
|
3346
|
+
CREATE INDEX IF NOT EXISTS runtime_scheduler_compute_billing_blocked_health_idx
|
|
3347
|
+
ON ${tableName('compute_billing_jobs_v2', options)}
|
|
3348
|
+
(blocked_at, lease_expires_at, created_at, run_id)
|
|
3349
|
+
WHERE status <> 'settled' AND blocked_at IS NOT NULL
|
|
3350
|
+
`);
|
|
3351
|
+
}
|
|
3201
3352
|
await client.query(`
|
|
3202
3353
|
CREATE INDEX IF NOT EXISTS runtime_scheduler_outbox_run_created_idx
|
|
3203
3354
|
ON ${tableName('outbox', options)} (run_id, created_at, event_id)
|
|
@@ -3274,6 +3425,28 @@ const POSTGRES_SCHEDULER_RUNTIME_ADMIN_INDEXES = [
|
|
|
3274
3425
|
definition: `(created_at, event_id)
|
|
3275
3426
|
WHERE delivered_at IS NULL AND failed_at IS NULL`,
|
|
3276
3427
|
},
|
|
3428
|
+
{
|
|
3429
|
+
name: 'runtime_scheduler_outbox_lease_health_idx',
|
|
3430
|
+
table: 'outbox',
|
|
3431
|
+
definition: `(lease_expires_at, created_at, event_id)
|
|
3432
|
+
WHERE delivered_at IS NULL
|
|
3433
|
+
AND failed_at IS NULL
|
|
3434
|
+
AND lease_owner IS NOT NULL`,
|
|
3435
|
+
},
|
|
3436
|
+
{
|
|
3437
|
+
name: 'runtime_scheduler_outbox_ready_health_idx',
|
|
3438
|
+
table: 'outbox',
|
|
3439
|
+
definition: `(coalesce(next_attempt_at, created_at), created_at, event_id)
|
|
3440
|
+
WHERE delivered_at IS NULL
|
|
3441
|
+
AND failed_at IS NULL
|
|
3442
|
+
AND lease_owner IS NULL`,
|
|
3443
|
+
},
|
|
3444
|
+
{
|
|
3445
|
+
name: 'runtime_scheduler_outbox_dead_health_idx',
|
|
3446
|
+
table: 'outbox',
|
|
3447
|
+
definition: `(failed_at, event_id)
|
|
3448
|
+
WHERE delivered_at IS NULL AND failed_at IS NOT NULL`,
|
|
3449
|
+
},
|
|
3277
3450
|
{
|
|
3278
3451
|
name: 'runtime_scheduler_outbox_admission_pending_idx',
|
|
3279
3452
|
table: 'outbox',
|
|
@@ -3297,6 +3470,48 @@ const POSTGRES_SCHEDULER_RUNTIME_ADMIN_INDEXES = [
|
|
|
3297
3470
|
definition: `(created_at, event_id)
|
|
3298
3471
|
WHERE delivered_at IS NULL AND failed_at IS NOT NULL`,
|
|
3299
3472
|
},
|
|
3473
|
+
{
|
|
3474
|
+
name: 'runtime_scheduler_sandbox_cleanup_v2_ready_health_idx',
|
|
3475
|
+
table: 'sandbox_cleanup_jobs_v2',
|
|
3476
|
+
definition: `(available_at, created_at, provider, sandbox_id)
|
|
3477
|
+
WHERE status <> 'deleted'
|
|
3478
|
+
AND blocked_at IS NULL
|
|
3479
|
+
AND lease_owner IS NULL
|
|
3480
|
+
AND status <> 'deleting'`,
|
|
3481
|
+
},
|
|
3482
|
+
{
|
|
3483
|
+
name: 'runtime_scheduler_sandbox_cleanup_v2_lease_health_idx',
|
|
3484
|
+
table: 'sandbox_cleanup_jobs_v2',
|
|
3485
|
+
definition: `(lease_expires_at, created_at, provider, sandbox_id)
|
|
3486
|
+
WHERE status <> 'deleted' AND lease_owner IS NOT NULL`,
|
|
3487
|
+
},
|
|
3488
|
+
{
|
|
3489
|
+
name: 'runtime_scheduler_sandbox_cleanup_v2_blocked_health_idx',
|
|
3490
|
+
table: 'sandbox_cleanup_jobs_v2',
|
|
3491
|
+
definition: `(blocked_at, lease_expires_at, created_at, provider, sandbox_id)
|
|
3492
|
+
WHERE status <> 'deleted'
|
|
3493
|
+
AND (blocked_at IS NOT NULL OR status = 'deleting')`,
|
|
3494
|
+
},
|
|
3495
|
+
{
|
|
3496
|
+
name: 'runtime_scheduler_compute_billing_ready_health_idx',
|
|
3497
|
+
table: 'compute_billing_jobs_v2',
|
|
3498
|
+
definition: `(available_at, created_at, run_id)
|
|
3499
|
+
WHERE status <> 'settled'
|
|
3500
|
+
AND blocked_at IS NULL
|
|
3501
|
+
AND lease_owner IS NULL`,
|
|
3502
|
+
},
|
|
3503
|
+
{
|
|
3504
|
+
name: 'runtime_scheduler_compute_billing_lease_health_idx',
|
|
3505
|
+
table: 'compute_billing_jobs_v2',
|
|
3506
|
+
definition: `(lease_expires_at, created_at, run_id)
|
|
3507
|
+
WHERE status <> 'settled' AND lease_owner IS NOT NULL`,
|
|
3508
|
+
},
|
|
3509
|
+
{
|
|
3510
|
+
name: 'runtime_scheduler_compute_billing_blocked_health_idx',
|
|
3511
|
+
table: 'compute_billing_jobs_v2',
|
|
3512
|
+
definition: `(blocked_at, lease_expires_at, created_at, run_id)
|
|
3513
|
+
WHERE status <> 'settled' AND blocked_at IS NOT NULL`,
|
|
3514
|
+
},
|
|
3300
3515
|
{
|
|
3301
3516
|
name: 'runtime_scheduler_runs_terminal_finished_idx',
|
|
3302
3517
|
table: 'runs',
|