@opengeni/db 0.28.9 → 0.31.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/dist/attached-browser-devices.d.ts +42 -0
- package/dist/attempt-tool-catalogs.d.ts +16 -0
- package/dist/browser-auth.d.ts +91 -0
- package/dist/browser-identities.d.ts +128 -0
- package/dist/browser-sessions.d.ts +272 -0
- package/dist/browser-state-artifacts.d.ts +17 -0
- package/dist/capability-components.d.ts +37 -0
- package/dist/capability-integrations.d.ts +192 -0
- package/dist/chunk-F5FT7BEZ.js +3535 -0
- package/dist/chunk-F5FT7BEZ.js.map +1 -0
- package/dist/chunk-ISI2TIUG.js +639 -0
- package/dist/chunk-ISI2TIUG.js.map +1 -0
- package/dist/chunk-MWDVXQOL.js +11639 -0
- package/dist/chunk-MWDVXQOL.js.map +1 -0
- package/dist/chunk-NBE6CHRI.js +955 -0
- package/dist/chunk-NBE6CHRI.js.map +1 -0
- package/dist/{chunk-VHBFHMPC.js → chunk-YHZXQ7HP.js} +754 -11
- package/dist/chunk-YHZXQ7HP.js.map +1 -0
- package/dist/codemode-operations.d.ts +117 -0
- package/dist/codex-token-resolver.d.ts +2 -2
- package/dist/company-profile-schema.d.ts +798 -0
- package/dist/company-profile.d.ts +268 -0
- package/dist/computer-sessions.d.ts +109 -0
- package/dist/connection-token-resolver.d.ts +9 -4
- package/dist/database.d.ts +52 -3
- package/dist/editable-artifact-durable-export.d.ts +153 -0
- package/dist/editable-artifact-durable-export.js +788 -0
- package/dist/editable-artifact-durable-export.js.map +1 -0
- package/dist/editable-artifact-materialization.d.ts +123 -0
- package/dist/editable-artifacts-schema.d.ts +4152 -0
- package/dist/editable-artifacts.d.ts +610 -0
- package/dist/editable-artifacts.js +26 -0
- package/dist/editable-artifacts.js.map +1 -0
- package/dist/generated-images.d.ts +139 -0
- package/dist/index.d.ts +698 -111
- package/dist/index.js +27573 -10322
- package/dist/index.js.map +1 -1
- package/dist/insights.d.ts +51 -4
- package/dist/integration-bindings.d.ts +70 -0
- package/dist/integration-features.d.ts +99 -0
- package/dist/interaction-revisions.d.ts +3 -0
- package/dist/interaction-schema.d.ts +5372 -0
- package/dist/knowledge-source-sync-schema.d.ts +1679 -0
- package/dist/knowledge-source-sync.d.ts +274 -0
- package/dist/memory-governance.d.ts +2 -2
- package/dist/memory-slack-delivery.d.ts +101 -0
- package/dist/new-session-drafts.d.ts +2 -2
- package/dist/pack-components.d.ts +76 -0
- package/dist/pack-installations.d.ts +86 -0
- package/dist/persistence-errors.d.ts +3 -3
- package/dist/plugin-packages.d.ts +126 -0
- package/dist/preference-registry.d.ts +1 -1
- package/dist/provision-roles.d.ts +9 -1
- package/dist/provision-roles.js +1 -1
- package/dist/runtime-posture.d.ts +18 -6
- package/dist/schema.d.ts +18342 -9099
- package/dist/schema.js +165 -1
- package/dist/scoped-knowledge.d.ts +97 -1
- package/dist/session-control.d.ts +4 -4
- package/dist/session-queue-commands.d.ts +19 -11
- package/dist/session-realtime-context.d.ts +2 -2
- package/dist/session-realtime-ledger.d.ts +4 -4
- package/dist/session-realtime-mirror.d.ts +2 -2
- package/dist/session-realtime-state.d.ts +1 -1
- package/dist/session-realtime-terminal.d.ts +1 -1
- package/dist/session-realtime.d.ts +7 -7
- package/dist/session-tool-call-settlement.d.ts +1 -1
- package/dist/slack-user-link-access.d.ts +54 -0
- package/dist/transcription-recordings.d.ts +2 -2
- package/dist/turn-initiator.d.ts +2 -2
- package/dist/video-generation.d.ts +216 -0
- package/dist/video-generation.js +66 -0
- package/dist/video-generation.js.map +1 -0
- package/dist/workspace-artifacts.d.ts +1 -1
- package/dist/workspace-instruction-policies.d.ts +1 -1
- package/dist/workspace-learning-policy-schema.d.ts +932 -0
- package/dist/workspace-learning-policy.d.ts +161 -0
- package/drizzle/0183_model_call_provider_cost_estimates.sql +39 -0
- package/drizzle/0184_sandbox_drain_teardown_fence.sql +682 -0
- package/drizzle/0185_temporal_schedule_cleanup_outbox.sql +168 -0
- package/drizzle/0186_sandbox_capture_provider_contract.sql +400 -0
- package/drizzle/0187_generated_image_artifacts.sql +173 -0
- package/drizzle/0188_image_generation_retention_failure.sql +25 -0
- package/drizzle/0189_retained_session_image_formats.sql +13 -0
- package/drizzle/0190_timeline_annotations.sql +31 -0
- package/drizzle/0191_editable_artifact_engine.sql +3853 -0
- package/drizzle/0192_editable_artifact_live_tickets.sql +338 -0
- package/drizzle/0193_editable_artifact_authorization.sql +190 -0
- package/drizzle/0194_editable_artifact_durable_exports.sql +160 -0
- package/drizzle/0195_editable_artifact_import_authorization.sql +203 -0
- package/drizzle/0196_rig_provider_images.sql +152 -0
- package/drizzle/0197_knowledge_source_sync_schedules.sql +523 -0
- package/drizzle/0198_memory_slack_publication_delivery.sql +393 -0
- package/drizzle/0199_workspace_learning_policy.sql +980 -0
- package/drizzle/0201_company_profile_authority.sql +849 -0
- package/drizzle/0202_document_index_checkpoints.sql +85 -0
- package/drizzle/0203_durable_video_generation.sql +353 -0
- package/drizzle/0204_video_generation_funding.sql +44 -0
- package/drizzle/0205_attempt_tool_catalogs.sql +230 -0
- package/drizzle/0206_browser_sessions.sql +646 -0
- package/drizzle/0207_browser_identities.sql +379 -0
- package/drizzle/0208_attached_browser_devices.sql +165 -0
- package/drizzle/0209_computer_sessions.sql +575 -0
- package/drizzle/0210_browser_auth_network_interventions.sql +441 -0
- package/drizzle/0211_editable_artifact_session_links.sql +58 -0
- package/drizzle/0212_slack_installation_bindings.sql +348 -0
- package/drizzle/0213_slack_user_link_access_requests.sql +177 -0
- package/drizzle/0214_session_activity_commit_gate.sql +262 -0
- package/drizzle/0215_capabilities_platform.sql +980 -0
- package/drizzle/0216_pack_component_ownership.sql +235 -0
- package/drizzle/0217_capability_definition_delete_authority.sql +32 -0
- package/package.json +18 -5
- package/src/attached-browser-devices.ts +371 -0
- package/src/attempt-tool-catalogs.ts +131 -0
- package/src/browser-auth.ts +1896 -0
- package/src/browser-identities.ts +1168 -0
- package/src/browser-sessions.ts +2005 -0
- package/src/browser-state-artifacts.ts +59 -0
- package/src/capability-components.ts +166 -0
- package/src/capability-integrations.ts +1663 -0
- package/src/codemode-operations.ts +674 -0
- package/src/company-profile-schema.ts +143 -0
- package/src/company-profile.ts +968 -0
- package/src/computer-sessions.ts +1130 -0
- package/src/connection-token-resolver.ts +270 -25
- package/src/database.ts +427 -23
- package/src/editable-artifact-durable-export.ts +1201 -0
- package/src/editable-artifact-materialization.ts +893 -0
- package/src/editable-artifacts-schema.ts +879 -0
- package/src/editable-artifacts.ts +5404 -0
- package/src/generated-images.ts +740 -0
- package/src/index.ts +5917 -1182
- package/src/insights.ts +160 -13
- package/src/integration-bindings.ts +455 -0
- package/src/integration-features.ts +859 -0
- package/src/interaction-revisions.ts +40 -0
- package/src/interaction-schema.ts +1303 -0
- package/src/knowledge-source-sync-schema.ts +192 -0
- package/src/knowledge-source-sync.ts +1922 -0
- package/src/memory-slack-delivery.ts +801 -0
- package/src/pack-components.ts +954 -0
- package/src/pack-installations.ts +929 -0
- package/src/persistence-errors.ts +4 -7
- package/src/plugin-packages.ts +1186 -0
- package/src/provision-roles.ts +302 -1
- package/src/runtime-posture-cli.ts +9 -0
- package/src/runtime-posture.ts +508 -5
- package/src/schema.ts +5117 -3119
- package/src/scoped-knowledge-schema.ts +1 -1
- package/src/scoped-knowledge.ts +655 -3
- package/src/session-control.ts +8 -5
- package/src/session-queue-commands.ts +187 -14
- package/src/session-realtime-context.ts +2 -2
- package/src/session-realtime-ledger.ts +3 -3
- package/src/session-realtime.ts +7 -7
- package/src/session-tool-call-settlement.ts +9 -0
- package/src/slack-user-link-access.ts +702 -0
- package/src/video-generation.ts +1452 -0
- package/src/workspace-learning-policy-schema.ts +139 -0
- package/src/workspace-learning-policy.ts +595 -0
- package/dist/chunk-P6CUHXQZ.js +0 -7248
- package/dist/chunk-P6CUHXQZ.js.map +0 -1
- package/dist/chunk-VHBFHMPC.js.map +0 -1
|
@@ -0,0 +1,646 @@
|
|
|
1
|
+
-- deployment-mode: maintenance
|
|
2
|
+
-- Canonical BrowserSession resource and interaction-holder authority. Every
|
|
3
|
+
-- application/worker writer is upgraded together; no legacy holder protocol remains.
|
|
4
|
+
SET LOCAL lock_timeout = '5s';
|
|
5
|
+
SET LOCAL statement_timeout = '30s';
|
|
6
|
+
|
|
7
|
+
CREATE TABLE "workspace_interaction_revisions" (
|
|
8
|
+
"workspace_id" uuid PRIMARY KEY,
|
|
9
|
+
"account_id" uuid NOT NULL,
|
|
10
|
+
"revision" bigint NOT NULL DEFAULT 0,
|
|
11
|
+
"updated_at" timestamptz NOT NULL DEFAULT now(),
|
|
12
|
+
CONSTRAINT "workspace_interaction_revisions_workspace_account_fk"
|
|
13
|
+
FOREIGN KEY ("workspace_id", "account_id")
|
|
14
|
+
REFERENCES "workspaces"("id", "account_id") ON DELETE CASCADE,
|
|
15
|
+
CONSTRAINT "workspace_interaction_revisions_revision_check"
|
|
16
|
+
CHECK ("revision" >= 0)
|
|
17
|
+
);
|
|
18
|
+
|
|
19
|
+
CREATE TABLE "browser_sessions" (
|
|
20
|
+
"id" uuid PRIMARY KEY,
|
|
21
|
+
"account_id" uuid NOT NULL,
|
|
22
|
+
"workspace_id" uuid NOT NULL,
|
|
23
|
+
"name" text NOT NULL,
|
|
24
|
+
"lifecycle" text NOT NULL DEFAULT 'starting',
|
|
25
|
+
"placement_kind" text NOT NULL,
|
|
26
|
+
"sandbox_group_id" uuid,
|
|
27
|
+
"connected_sandbox_id" uuid,
|
|
28
|
+
"device_id" uuid,
|
|
29
|
+
"external_provider_id" text,
|
|
30
|
+
"external_placement_id" text,
|
|
31
|
+
"controller_id" text,
|
|
32
|
+
"controller_generation" text,
|
|
33
|
+
"placement_instance_id" text,
|
|
34
|
+
"token_generation" integer NOT NULL DEFAULT 1,
|
|
35
|
+
"driver_id" text NOT NULL,
|
|
36
|
+
"engine" text NOT NULL,
|
|
37
|
+
"engine_version" text,
|
|
38
|
+
"headless" boolean NOT NULL,
|
|
39
|
+
"identity_id" uuid,
|
|
40
|
+
"base_revision_id" uuid,
|
|
41
|
+
"linked_computer_session_id" uuid,
|
|
42
|
+
"network_route_id" uuid,
|
|
43
|
+
"private_checkpoint_artifact_id" uuid,
|
|
44
|
+
"capabilities" jsonb NOT NULL,
|
|
45
|
+
"create_operation_id" uuid NOT NULL,
|
|
46
|
+
"created_by_subject_id" text NOT NULL,
|
|
47
|
+
"failure_code" text,
|
|
48
|
+
"controller_heartbeat_at" timestamptz,
|
|
49
|
+
"created_at" timestamptz NOT NULL DEFAULT now(),
|
|
50
|
+
"last_used_at" timestamptz NOT NULL DEFAULT now(),
|
|
51
|
+
"updated_at" timestamptz NOT NULL DEFAULT now(),
|
|
52
|
+
CONSTRAINT "browser_sessions_workspace_account_fk"
|
|
53
|
+
FOREIGN KEY ("workspace_id", "account_id")
|
|
54
|
+
REFERENCES "workspaces"("id", "account_id") ON DELETE CASCADE,
|
|
55
|
+
CONSTRAINT "browser_sessions_lifecycle_check" CHECK (
|
|
56
|
+
"lifecycle" IN (
|
|
57
|
+
'starting', 'active', 'suspending', 'suspended', 'restoring',
|
|
58
|
+
'repair_required', 'lost', 'ending', 'ended', 'failed'
|
|
59
|
+
)
|
|
60
|
+
),
|
|
61
|
+
CONSTRAINT "browser_sessions_engine_check" CHECK (
|
|
62
|
+
"engine" IN ('chromium', 'chrome', 'firefox', 'webkit', 'lightpanda', 'external')
|
|
63
|
+
),
|
|
64
|
+
CONSTRAINT "browser_sessions_values_check" CHECK (
|
|
65
|
+
octet_length("name") BETWEEN 1 AND 200
|
|
66
|
+
AND octet_length("driver_id") BETWEEN 1 AND 512
|
|
67
|
+
AND octet_length("created_by_subject_id") BETWEEN 1 AND 1024
|
|
68
|
+
AND "token_generation" > 0
|
|
69
|
+
AND jsonb_typeof("capabilities") = 'object'
|
|
70
|
+
AND octet_length("capabilities"::text) BETWEEN 2 AND 65536
|
|
71
|
+
AND ("engine_version" IS NULL OR octet_length("engine_version") BETWEEN 1 AND 256)
|
|
72
|
+
AND ("failure_code" IS NULL OR octet_length("failure_code") BETWEEN 1 AND 512)
|
|
73
|
+
),
|
|
74
|
+
CONSTRAINT "browser_sessions_placement_check" CHECK (
|
|
75
|
+
(
|
|
76
|
+
"placement_kind" = 'sandbox_group'
|
|
77
|
+
AND "sandbox_group_id" IS NOT NULL
|
|
78
|
+
AND "connected_sandbox_id" IS NULL
|
|
79
|
+
AND "device_id" IS NULL
|
|
80
|
+
AND "external_provider_id" IS NULL
|
|
81
|
+
AND "external_placement_id" IS NULL
|
|
82
|
+
) OR (
|
|
83
|
+
"placement_kind" = 'connected_machine'
|
|
84
|
+
AND "sandbox_group_id" IS NULL
|
|
85
|
+
AND "connected_sandbox_id" IS NOT NULL
|
|
86
|
+
AND "device_id" IS NULL
|
|
87
|
+
AND "external_provider_id" IS NULL
|
|
88
|
+
AND "external_placement_id" IS NULL
|
|
89
|
+
) OR (
|
|
90
|
+
"placement_kind" = 'attached_device'
|
|
91
|
+
AND "sandbox_group_id" IS NULL
|
|
92
|
+
AND "connected_sandbox_id" IS NULL
|
|
93
|
+
AND "device_id" IS NOT NULL
|
|
94
|
+
AND "external_provider_id" IS NULL
|
|
95
|
+
AND "external_placement_id" IS NULL
|
|
96
|
+
) OR (
|
|
97
|
+
"placement_kind" = 'external_provider'
|
|
98
|
+
AND "sandbox_group_id" IS NULL
|
|
99
|
+
AND "connected_sandbox_id" IS NULL
|
|
100
|
+
AND "device_id" IS NULL
|
|
101
|
+
AND "external_provider_id" IS NOT NULL
|
|
102
|
+
AND "external_placement_id" IS NOT NULL
|
|
103
|
+
AND octet_length("external_provider_id") BETWEEN 1 AND 512
|
|
104
|
+
AND octet_length("external_placement_id") BETWEEN 1 AND 512
|
|
105
|
+
)
|
|
106
|
+
),
|
|
107
|
+
CONSTRAINT "browser_sessions_controller_check" CHECK (
|
|
108
|
+
(
|
|
109
|
+
"controller_id" IS NULL
|
|
110
|
+
AND "controller_generation" IS NULL
|
|
111
|
+
AND "placement_instance_id" IS NULL
|
|
112
|
+
AND "controller_heartbeat_at" IS NULL
|
|
113
|
+
) OR (
|
|
114
|
+
"controller_id" IS NOT NULL
|
|
115
|
+
AND octet_length("controller_id") BETWEEN 1 AND 512
|
|
116
|
+
AND "controller_generation" IS NOT NULL
|
|
117
|
+
AND octet_length("controller_generation") BETWEEN 1 AND 256
|
|
118
|
+
AND "placement_instance_id" IS NOT NULL
|
|
119
|
+
AND octet_length("placement_instance_id") BETWEEN 1 AND 512
|
|
120
|
+
AND "controller_heartbeat_at" IS NOT NULL
|
|
121
|
+
)
|
|
122
|
+
),
|
|
123
|
+
CONSTRAINT "browser_sessions_identity_revision_check"
|
|
124
|
+
CHECK ("base_revision_id" IS NULL OR "identity_id" IS NOT NULL),
|
|
125
|
+
CONSTRAINT "browser_sessions_failure_check" CHECK (
|
|
126
|
+
(
|
|
127
|
+
"lifecycle" IN ('repair_required', 'lost', 'failed')
|
|
128
|
+
AND "failure_code" IS NOT NULL
|
|
129
|
+
) OR (
|
|
130
|
+
"lifecycle" NOT IN ('repair_required', 'lost', 'failed')
|
|
131
|
+
AND "failure_code" IS NULL
|
|
132
|
+
)
|
|
133
|
+
),
|
|
134
|
+
CONSTRAINT "browser_sessions_workspace_id_uq" UNIQUE ("workspace_id", "id"),
|
|
135
|
+
CONSTRAINT "browser_sessions_workspace_create_operation_uq"
|
|
136
|
+
UNIQUE ("workspace_id", "create_operation_id")
|
|
137
|
+
);
|
|
138
|
+
|
|
139
|
+
CREATE INDEX "browser_sessions_workspace_lifecycle_idx"
|
|
140
|
+
ON "browser_sessions" ("workspace_id", "lifecycle", "last_used_at", "id");
|
|
141
|
+
CREATE INDEX "browser_sessions_sandbox_group_idx"
|
|
142
|
+
ON "browser_sessions" ("workspace_id", "sandbox_group_id", "lifecycle");
|
|
143
|
+
|
|
144
|
+
CREATE TABLE "browser_session_associations" (
|
|
145
|
+
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
146
|
+
"account_id" uuid NOT NULL,
|
|
147
|
+
"workspace_id" uuid NOT NULL,
|
|
148
|
+
"browser_session_id" uuid NOT NULL,
|
|
149
|
+
"session_id" uuid NOT NULL,
|
|
150
|
+
"turn_id" uuid,
|
|
151
|
+
"attempt_id" uuid,
|
|
152
|
+
"relationship" text NOT NULL,
|
|
153
|
+
"actor_subject_id" text NOT NULL,
|
|
154
|
+
"last_used_at" timestamptz NOT NULL DEFAULT now(),
|
|
155
|
+
"created_at" timestamptz NOT NULL DEFAULT now(),
|
|
156
|
+
CONSTRAINT "browser_session_associations_workspace_account_fk"
|
|
157
|
+
FOREIGN KEY ("workspace_id", "account_id")
|
|
158
|
+
REFERENCES "workspaces"("id", "account_id") ON DELETE CASCADE,
|
|
159
|
+
CONSTRAINT "browser_session_associations_resource_fk"
|
|
160
|
+
FOREIGN KEY ("workspace_id", "browser_session_id")
|
|
161
|
+
REFERENCES "browser_sessions"("workspace_id", "id") ON DELETE CASCADE,
|
|
162
|
+
CONSTRAINT "browser_session_associations_session_fk"
|
|
163
|
+
FOREIGN KEY ("workspace_id", "session_id")
|
|
164
|
+
REFERENCES "sessions"("workspace_id", "id") ON DELETE CASCADE,
|
|
165
|
+
CONSTRAINT "browser_session_associations_turn_fk"
|
|
166
|
+
FOREIGN KEY ("workspace_id", "turn_id")
|
|
167
|
+
REFERENCES "session_turns"("workspace_id", "id") ON DELETE SET NULL ("turn_id"),
|
|
168
|
+
CONSTRAINT "browser_session_associations_attempt_fk"
|
|
169
|
+
FOREIGN KEY ("workspace_id", "attempt_id")
|
|
170
|
+
REFERENCES "session_turn_attempts"("workspace_id", "id") ON DELETE SET NULL ("attempt_id"),
|
|
171
|
+
CONSTRAINT "browser_session_associations_relationship_check"
|
|
172
|
+
CHECK ("relationship" IN ('created', 'using', 'observing', 'related')),
|
|
173
|
+
CONSTRAINT "browser_session_associations_values_check" CHECK (
|
|
174
|
+
octet_length("actor_subject_id") BETWEEN 1 AND 1024
|
|
175
|
+
AND ("attempt_id" IS NULL OR "turn_id" IS NOT NULL)
|
|
176
|
+
),
|
|
177
|
+
CONSTRAINT "browser_session_associations_resource_session_relationship_uq"
|
|
178
|
+
UNIQUE ("browser_session_id", "session_id", "relationship")
|
|
179
|
+
);
|
|
180
|
+
|
|
181
|
+
CREATE INDEX "browser_session_associations_workspace_session_idx"
|
|
182
|
+
ON "browser_session_associations" ("workspace_id", "session_id", "last_used_at");
|
|
183
|
+
CREATE INDEX "browser_session_associations_resource_idx"
|
|
184
|
+
ON "browser_session_associations" ("workspace_id", "browser_session_id", "last_used_at");
|
|
185
|
+
|
|
186
|
+
CREATE TABLE "interaction_operations" (
|
|
187
|
+
"operation_id" uuid PRIMARY KEY,
|
|
188
|
+
"account_id" uuid NOT NULL,
|
|
189
|
+
"workspace_id" uuid NOT NULL,
|
|
190
|
+
"resource_kind" text NOT NULL,
|
|
191
|
+
"resource_id" uuid NOT NULL,
|
|
192
|
+
"kind" text NOT NULL,
|
|
193
|
+
"request_digest" text NOT NULL,
|
|
194
|
+
"state" text NOT NULL DEFAULT 'prepared',
|
|
195
|
+
"controller_generation" text,
|
|
196
|
+
"error_code" text,
|
|
197
|
+
"error_message" text,
|
|
198
|
+
"error_retryable" boolean,
|
|
199
|
+
"error_details" jsonb,
|
|
200
|
+
"actor_subject_id" text NOT NULL,
|
|
201
|
+
"created_at" timestamptz NOT NULL DEFAULT now(),
|
|
202
|
+
"dispatched_at" timestamptz,
|
|
203
|
+
"settled_at" timestamptz,
|
|
204
|
+
"updated_at" timestamptz NOT NULL DEFAULT now(),
|
|
205
|
+
CONSTRAINT "interaction_operations_workspace_account_fk"
|
|
206
|
+
FOREIGN KEY ("workspace_id", "account_id")
|
|
207
|
+
REFERENCES "workspaces"("id", "account_id") ON DELETE CASCADE,
|
|
208
|
+
CONSTRAINT "interaction_operations_resource_kind_check"
|
|
209
|
+
CHECK ("resource_kind" IN ('browser_session', 'computer_session')),
|
|
210
|
+
CONSTRAINT "interaction_operations_kind_check"
|
|
211
|
+
CHECK ("kind" IN ('create', 'resume', 'suspend', 'end')),
|
|
212
|
+
CONSTRAINT "interaction_operations_state_check"
|
|
213
|
+
CHECK ("state" IN ('prepared', 'dispatched', 'completed', 'failed', 'outcome_unknown')),
|
|
214
|
+
CONSTRAINT "interaction_operations_values_check" CHECK (
|
|
215
|
+
"request_digest" ~ '^[0-9a-f]{64}$'
|
|
216
|
+
AND octet_length("actor_subject_id") BETWEEN 1 AND 1024
|
|
217
|
+
AND ("controller_generation" IS NULL OR octet_length("controller_generation") BETWEEN 1 AND 256)
|
|
218
|
+
AND ("error_code" IS NULL OR octet_length("error_code") BETWEEN 1 AND 512)
|
|
219
|
+
AND ("error_message" IS NULL OR octet_length("error_message") BETWEEN 1 AND 8192)
|
|
220
|
+
AND ("error_details" IS NULL OR (
|
|
221
|
+
jsonb_typeof("error_details") = 'object'
|
|
222
|
+
AND octet_length("error_details"::text) BETWEEN 2 AND 65536
|
|
223
|
+
))
|
|
224
|
+
),
|
|
225
|
+
CONSTRAINT "interaction_operations_lifecycle_check" CHECK (
|
|
226
|
+
(
|
|
227
|
+
"state" = 'prepared'
|
|
228
|
+
AND "dispatched_at" IS NULL
|
|
229
|
+
AND "settled_at" IS NULL
|
|
230
|
+
AND "error_code" IS NULL
|
|
231
|
+
AND "error_message" IS NULL
|
|
232
|
+
AND "error_retryable" IS NULL
|
|
233
|
+
AND "error_details" IS NULL
|
|
234
|
+
) OR (
|
|
235
|
+
"state" = 'dispatched'
|
|
236
|
+
AND "dispatched_at" IS NOT NULL
|
|
237
|
+
AND "settled_at" IS NULL
|
|
238
|
+
AND "error_code" IS NULL
|
|
239
|
+
AND "error_message" IS NULL
|
|
240
|
+
AND "error_retryable" IS NULL
|
|
241
|
+
AND "error_details" IS NULL
|
|
242
|
+
) OR (
|
|
243
|
+
"state" = 'completed'
|
|
244
|
+
AND "dispatched_at" IS NOT NULL
|
|
245
|
+
AND "settled_at" IS NOT NULL
|
|
246
|
+
AND "error_code" IS NULL
|
|
247
|
+
AND "error_message" IS NULL
|
|
248
|
+
AND "error_retryable" IS NULL
|
|
249
|
+
AND "error_details" IS NULL
|
|
250
|
+
) OR (
|
|
251
|
+
"state" IN ('failed', 'outcome_unknown')
|
|
252
|
+
AND "settled_at" IS NOT NULL
|
|
253
|
+
AND "error_code" IS NOT NULL
|
|
254
|
+
AND "error_message" IS NOT NULL
|
|
255
|
+
AND "error_retryable" IS NOT NULL
|
|
256
|
+
)
|
|
257
|
+
),
|
|
258
|
+
CONSTRAINT "interaction_operations_workspace_operation_uq"
|
|
259
|
+
UNIQUE ("workspace_id", "operation_id")
|
|
260
|
+
);
|
|
261
|
+
|
|
262
|
+
CREATE INDEX "interaction_operations_resource_history_idx"
|
|
263
|
+
ON "interaction_operations" (
|
|
264
|
+
"workspace_id", "resource_kind", "resource_id", "created_at"
|
|
265
|
+
);
|
|
266
|
+
CREATE UNIQUE INDEX "interaction_operations_active_resource_uq"
|
|
267
|
+
ON "interaction_operations" ("workspace_id", "resource_kind", "resource_id")
|
|
268
|
+
WHERE "state" IN ('prepared', 'dispatched');
|
|
269
|
+
|
|
270
|
+
ALTER TABLE "browser_sessions"
|
|
271
|
+
ADD CONSTRAINT "browser_sessions_create_operation_fk"
|
|
272
|
+
FOREIGN KEY ("workspace_id", "create_operation_id")
|
|
273
|
+
REFERENCES "interaction_operations"("workspace_id", "operation_id") ON DELETE RESTRICT;
|
|
274
|
+
|
|
275
|
+
ALTER TABLE "sandbox_lease_holders"
|
|
276
|
+
DROP CONSTRAINT "sandbox_lease_holders_kind_check";
|
|
277
|
+
ALTER TABLE "sandbox_lease_holders"
|
|
278
|
+
ADD CONSTRAINT "sandbox_lease_holders_kind_check"
|
|
279
|
+
CHECK ("kind" IN ('turn', 'viewer', 'direct', 'process', 'interaction'));
|
|
280
|
+
|
|
281
|
+
ALTER TABLE "workspace_interaction_revisions" ENABLE ROW LEVEL SECURITY;
|
|
282
|
+
ALTER TABLE "workspace_interaction_revisions" FORCE ROW LEVEL SECURITY;
|
|
283
|
+
CREATE POLICY workspace_isolation ON "workspace_interaction_revisions"
|
|
284
|
+
USING (opengeni_private.workspace_rls_visible("account_id", "workspace_id"))
|
|
285
|
+
WITH CHECK (opengeni_private.workspace_rls_visible("account_id", "workspace_id"));
|
|
286
|
+
|
|
287
|
+
ALTER TABLE "browser_sessions" ENABLE ROW LEVEL SECURITY;
|
|
288
|
+
ALTER TABLE "browser_sessions" FORCE ROW LEVEL SECURITY;
|
|
289
|
+
CREATE POLICY workspace_isolation ON "browser_sessions"
|
|
290
|
+
USING (opengeni_private.workspace_rls_visible("account_id", "workspace_id"))
|
|
291
|
+
WITH CHECK (opengeni_private.workspace_rls_visible("account_id", "workspace_id"));
|
|
292
|
+
|
|
293
|
+
ALTER TABLE "browser_session_associations" ENABLE ROW LEVEL SECURITY;
|
|
294
|
+
ALTER TABLE "browser_session_associations" FORCE ROW LEVEL SECURITY;
|
|
295
|
+
CREATE POLICY workspace_isolation ON "browser_session_associations"
|
|
296
|
+
USING (opengeni_private.workspace_rls_visible("account_id", "workspace_id"))
|
|
297
|
+
WITH CHECK (opengeni_private.workspace_rls_visible("account_id", "workspace_id"));
|
|
298
|
+
|
|
299
|
+
ALTER TABLE "interaction_operations" ENABLE ROW LEVEL SECURITY;
|
|
300
|
+
ALTER TABLE "interaction_operations" FORCE ROW LEVEL SECURITY;
|
|
301
|
+
CREATE POLICY workspace_isolation ON "interaction_operations"
|
|
302
|
+
USING (opengeni_private.workspace_rls_visible("account_id", "workspace_id"))
|
|
303
|
+
WITH CHECK (opengeni_private.workspace_rls_visible("account_id", "workspace_id"));
|
|
304
|
+
|
|
305
|
+
DO $grants$
|
|
306
|
+
DECLARE target_schema text := current_schema();
|
|
307
|
+
BEGIN
|
|
308
|
+
IF EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'opengeni_app') THEN
|
|
309
|
+
EXECUTE format(
|
|
310
|
+
'REVOKE ALL ON TABLE %I.workspace_interaction_revisions, %I.browser_sessions, %I.browser_session_associations, %I.interaction_operations FROM opengeni_app',
|
|
311
|
+
target_schema,
|
|
312
|
+
target_schema,
|
|
313
|
+
target_schema,
|
|
314
|
+
target_schema
|
|
315
|
+
);
|
|
316
|
+
EXECUTE format(
|
|
317
|
+
'GRANT SELECT, INSERT, UPDATE ON TABLE %I.workspace_interaction_revisions TO opengeni_app',
|
|
318
|
+
target_schema
|
|
319
|
+
);
|
|
320
|
+
EXECUTE format(
|
|
321
|
+
'GRANT SELECT, INSERT, UPDATE ON TABLE %I.browser_sessions TO opengeni_app',
|
|
322
|
+
target_schema
|
|
323
|
+
);
|
|
324
|
+
EXECUTE format(
|
|
325
|
+
'GRANT SELECT, INSERT, UPDATE, DELETE ON TABLE %I.browser_session_associations TO opengeni_app',
|
|
326
|
+
target_schema
|
|
327
|
+
);
|
|
328
|
+
EXECUTE format(
|
|
329
|
+
'GRANT SELECT, INSERT, UPDATE ON TABLE %I.interaction_operations TO opengeni_app',
|
|
330
|
+
target_schema
|
|
331
|
+
);
|
|
332
|
+
END IF;
|
|
333
|
+
END
|
|
334
|
+
$grants$;
|
|
335
|
+
|
|
336
|
+
-- The mega-PR is a maintenance cutover, so the global reaper has one exact
|
|
337
|
+
-- four-argument contract. Interaction holders are controller-heartbeat-bound;
|
|
338
|
+
-- a dead controller makes its BrowserSession visibly lost before the box drains.
|
|
339
|
+
DROP FUNCTION opengeni_private.reap_sandbox_leases(bigint, bigint, bigint);
|
|
340
|
+
|
|
341
|
+
DO $interaction_aware_reaper$
|
|
342
|
+
DECLARE data_schema text := current_schema();
|
|
343
|
+
BEGIN
|
|
344
|
+
EXECUTE format($create$
|
|
345
|
+
CREATE FUNCTION opengeni_private.reap_sandbox_leases(
|
|
346
|
+
p_viewer_holder_ttl_ms bigint,
|
|
347
|
+
p_turn_holder_ttl_ms bigint,
|
|
348
|
+
p_interaction_holder_ttl_ms bigint,
|
|
349
|
+
p_idle_grace_ms bigint
|
|
350
|
+
)
|
|
351
|
+
RETURNS TABLE (
|
|
352
|
+
workspace_id uuid,
|
|
353
|
+
sandbox_group_id uuid,
|
|
354
|
+
instance_id text,
|
|
355
|
+
lease_epoch integer
|
|
356
|
+
)
|
|
357
|
+
LANGUAGE plpgsql
|
|
358
|
+
SECURITY DEFINER
|
|
359
|
+
SET search_path = pg_catalog
|
|
360
|
+
AS $function$
|
|
361
|
+
DECLARE
|
|
362
|
+
locked_ids uuid[];
|
|
363
|
+
stale_interaction_ids uuid[];
|
|
364
|
+
changed_interaction_workspaces uuid[];
|
|
365
|
+
BEGIN
|
|
366
|
+
PERFORM pg_catalog.set_config('opengeni.sandbox_recovery_protocol_v2', '1', true);
|
|
367
|
+
|
|
368
|
+
SELECT coalesce(pg_catalog.array_agg(candidate.id), ARRAY[]::uuid[])
|
|
369
|
+
INTO locked_ids
|
|
370
|
+
FROM (
|
|
371
|
+
SELECT lease.id
|
|
372
|
+
FROM %1$I.sandbox_leases lease
|
|
373
|
+
WHERE lease.liveness <> 'cold'
|
|
374
|
+
OR EXISTS (
|
|
375
|
+
SELECT 1
|
|
376
|
+
FROM %1$I.sandbox_lease_holders holder
|
|
377
|
+
WHERE holder.lease_id = lease.id
|
|
378
|
+
)
|
|
379
|
+
ORDER BY lease.updated_at, lease.id
|
|
380
|
+
LIMIT 500
|
|
381
|
+
FOR UPDATE OF lease SKIP LOCKED
|
|
382
|
+
) candidate;
|
|
383
|
+
|
|
384
|
+
IF pg_catalog.cardinality(locked_ids) = 0 THEN
|
|
385
|
+
RETURN;
|
|
386
|
+
END IF;
|
|
387
|
+
|
|
388
|
+
DELETE FROM %1$I.sandbox_lease_holders holder
|
|
389
|
+
USING (
|
|
390
|
+
SELECT stale.id
|
|
391
|
+
FROM %1$I.sandbox_lease_holders stale
|
|
392
|
+
WHERE stale.lease_id = ANY(locked_ids)
|
|
393
|
+
AND stale.kind IN ('viewer', 'direct')
|
|
394
|
+
AND stale.last_heartbeat_at
|
|
395
|
+
< pg_catalog.now()
|
|
396
|
+
- pg_catalog.make_interval(secs => p_viewer_holder_ttl_ms / 1000.0)
|
|
397
|
+
FOR UPDATE OF stale SKIP LOCKED
|
|
398
|
+
) victim
|
|
399
|
+
WHERE holder.id = victim.id;
|
|
400
|
+
|
|
401
|
+
IF p_turn_holder_ttl_ms > 0 THEN
|
|
402
|
+
DELETE FROM %1$I.sandbox_lease_holders holder
|
|
403
|
+
USING (
|
|
404
|
+
SELECT stale.id
|
|
405
|
+
FROM %1$I.sandbox_lease_holders stale
|
|
406
|
+
WHERE stale.lease_id = ANY(locked_ids)
|
|
407
|
+
AND stale.kind = 'turn'
|
|
408
|
+
AND (
|
|
409
|
+
stale.last_heartbeat_at
|
|
410
|
+
< pg_catalog.now()
|
|
411
|
+
- pg_catalog.make_interval(secs => p_turn_holder_ttl_ms / 1000.0)
|
|
412
|
+
OR (
|
|
413
|
+
stale.holder_id ~* '^turn-attempt:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$'
|
|
414
|
+
AND NOT EXISTS (
|
|
415
|
+
SELECT 1
|
|
416
|
+
FROM %1$I.session_turn_attempts attempt
|
|
417
|
+
JOIN %1$I.session_turns turn
|
|
418
|
+
ON turn.account_id = attempt.account_id
|
|
419
|
+
AND turn.workspace_id = attempt.workspace_id
|
|
420
|
+
AND turn.session_id = attempt.session_id
|
|
421
|
+
AND turn.id = attempt.turn_id
|
|
422
|
+
AND turn.execution_generation = attempt.execution_generation
|
|
423
|
+
AND turn.active_attempt_id = attempt.id
|
|
424
|
+
WHERE stale.holder_id = ('turn-attempt:' || attempt.id::text)
|
|
425
|
+
AND attempt.account_id = stale.account_id
|
|
426
|
+
AND attempt.workspace_id = stale.workspace_id
|
|
427
|
+
AND attempt.session_id = stale.subject_id
|
|
428
|
+
AND attempt.state IN ('claimed', 'running')
|
|
429
|
+
)
|
|
430
|
+
)
|
|
431
|
+
)
|
|
432
|
+
FOR UPDATE OF stale SKIP LOCKED
|
|
433
|
+
) victim
|
|
434
|
+
WHERE holder.id = victim.id;
|
|
435
|
+
END IF;
|
|
436
|
+
|
|
437
|
+
IF p_interaction_holder_ttl_ms > 0 THEN
|
|
438
|
+
SELECT coalesce(pg_catalog.array_agg(candidate.id), ARRAY[]::uuid[])
|
|
439
|
+
INTO stale_interaction_ids
|
|
440
|
+
FROM (
|
|
441
|
+
SELECT stale.id
|
|
442
|
+
FROM %1$I.sandbox_lease_holders stale
|
|
443
|
+
WHERE stale.lease_id = ANY(locked_ids)
|
|
444
|
+
AND stale.kind = 'interaction'
|
|
445
|
+
AND (
|
|
446
|
+
stale.last_heartbeat_at
|
|
447
|
+
< pg_catalog.now()
|
|
448
|
+
- pg_catalog.make_interval(
|
|
449
|
+
secs => p_interaction_holder_ttl_ms / 1000.0
|
|
450
|
+
)
|
|
451
|
+
OR NOT EXISTS (
|
|
452
|
+
SELECT 1
|
|
453
|
+
FROM %1$I.browser_sessions browser
|
|
454
|
+
WHERE stale.holder_id = ('browser-session:' || browser.id::text)
|
|
455
|
+
AND browser.account_id = stale.account_id
|
|
456
|
+
AND browser.workspace_id = stale.workspace_id
|
|
457
|
+
AND browser.sandbox_group_id = (
|
|
458
|
+
SELECT lease.sandbox_group_id
|
|
459
|
+
FROM %1$I.sandbox_leases lease
|
|
460
|
+
WHERE lease.id = stale.lease_id
|
|
461
|
+
)
|
|
462
|
+
AND browser.lifecycle IN (
|
|
463
|
+
'starting', 'active', 'suspending', 'restoring', 'ending'
|
|
464
|
+
)
|
|
465
|
+
)
|
|
466
|
+
)
|
|
467
|
+
FOR UPDATE OF stale SKIP LOCKED
|
|
468
|
+
) candidate;
|
|
469
|
+
|
|
470
|
+
IF pg_catalog.cardinality(stale_interaction_ids) > 0 THEN
|
|
471
|
+
WITH updated AS (
|
|
472
|
+
UPDATE %1$I.browser_sessions browser
|
|
473
|
+
SET lifecycle = 'lost',
|
|
474
|
+
controller_id = null,
|
|
475
|
+
controller_generation = null,
|
|
476
|
+
placement_instance_id = null,
|
|
477
|
+
controller_heartbeat_at = null,
|
|
478
|
+
failure_code = 'controller_heartbeat_expired',
|
|
479
|
+
updated_at = pg_catalog.now()
|
|
480
|
+
FROM %1$I.sandbox_lease_holders holder
|
|
481
|
+
WHERE holder.id = ANY(stale_interaction_ids)
|
|
482
|
+
AND holder.holder_id = ('browser-session:' || browser.id::text)
|
|
483
|
+
AND holder.account_id = browser.account_id
|
|
484
|
+
AND holder.workspace_id = browser.workspace_id
|
|
485
|
+
AND browser.lifecycle IN (
|
|
486
|
+
'starting', 'active', 'suspending', 'restoring', 'ending'
|
|
487
|
+
)
|
|
488
|
+
RETURNING browser.workspace_id
|
|
489
|
+
)
|
|
490
|
+
SELECT coalesce(
|
|
491
|
+
pg_catalog.array_agg(DISTINCT updated.workspace_id),
|
|
492
|
+
ARRAY[]::uuid[]
|
|
493
|
+
)
|
|
494
|
+
INTO changed_interaction_workspaces
|
|
495
|
+
FROM updated;
|
|
496
|
+
|
|
497
|
+
DELETE FROM %1$I.sandbox_lease_holders holder
|
|
498
|
+
WHERE holder.id = ANY(stale_interaction_ids);
|
|
499
|
+
|
|
500
|
+
UPDATE %1$I.workspace_interaction_revisions revision
|
|
501
|
+
SET revision = revision.revision + 1,
|
|
502
|
+
updated_at = pg_catalog.now()
|
|
503
|
+
WHERE revision.workspace_id = ANY(changed_interaction_workspaces);
|
|
504
|
+
END IF;
|
|
505
|
+
END IF;
|
|
506
|
+
|
|
507
|
+
UPDATE %1$I.sandbox_leases lease SET
|
|
508
|
+
refcount = counts.total,
|
|
509
|
+
turn_holders = counts.turns,
|
|
510
|
+
viewer_holders = counts.viewers,
|
|
511
|
+
liveness = CASE
|
|
512
|
+
WHEN lease.liveness = 'warm'
|
|
513
|
+
AND counts.total = 0
|
|
514
|
+
AND counts.turns = 0
|
|
515
|
+
AND (
|
|
516
|
+
lease.reaper_hold_id IS NULL
|
|
517
|
+
OR lease.reaper_hold_until <= pg_catalog.now()
|
|
518
|
+
)
|
|
519
|
+
THEN 'draining' ELSE lease.liveness END,
|
|
520
|
+
expires_at = CASE
|
|
521
|
+
WHEN lease.liveness = 'warm'
|
|
522
|
+
AND counts.total = 0
|
|
523
|
+
AND counts.turns = 0
|
|
524
|
+
AND (
|
|
525
|
+
lease.reaper_hold_id IS NULL
|
|
526
|
+
OR lease.reaper_hold_until <= pg_catalog.now()
|
|
527
|
+
)
|
|
528
|
+
THEN CASE
|
|
529
|
+
WHEN lease.rotation_requested_at IS NOT NULL
|
|
530
|
+
OR lease.archive_capture_id IS NOT NULL
|
|
531
|
+
THEN pg_catalog.now() - interval '1 millisecond'
|
|
532
|
+
ELSE pg_catalog.now()
|
|
533
|
+
+ pg_catalog.make_interval(secs => p_idle_grace_ms / 1000.0)
|
|
534
|
+
END
|
|
535
|
+
ELSE lease.expires_at END,
|
|
536
|
+
updated_at = pg_catalog.now()
|
|
537
|
+
FROM (
|
|
538
|
+
SELECT candidate.id,
|
|
539
|
+
pg_catalog.count(holder.id)::int AS total,
|
|
540
|
+
pg_catalog.count(holder.id)
|
|
541
|
+
FILTER (WHERE holder.kind = 'turn')::int AS turns,
|
|
542
|
+
pg_catalog.count(holder.id)
|
|
543
|
+
FILTER (WHERE holder.kind = 'viewer')::int AS viewers
|
|
544
|
+
FROM pg_catalog.unnest(locked_ids) candidate(id)
|
|
545
|
+
LEFT JOIN %1$I.sandbox_lease_holders holder
|
|
546
|
+
ON holder.lease_id = candidate.id
|
|
547
|
+
GROUP BY candidate.id
|
|
548
|
+
) counts
|
|
549
|
+
WHERE lease.id = counts.id;
|
|
550
|
+
|
|
551
|
+
UPDATE %1$I.sandbox_leases lease SET
|
|
552
|
+
liveness = 'cold',
|
|
553
|
+
instance_id = null,
|
|
554
|
+
lease_epoch = lease.lease_epoch + 1,
|
|
555
|
+
reaper_hold_id = null,
|
|
556
|
+
reaper_hold_until = null,
|
|
557
|
+
reaper_hold_reason = null,
|
|
558
|
+
resume_state = opengeni_private.warming_reset_resume_state_v2(
|
|
559
|
+
lease.backend,
|
|
560
|
+
lease.resume_backend_id,
|
|
561
|
+
lease.resume_state,
|
|
562
|
+
lease.workspace_generation,
|
|
563
|
+
lease.archive_generation,
|
|
564
|
+
pg_catalog.clock_timestamp()
|
|
565
|
+
),
|
|
566
|
+
resume_backend_id = CASE
|
|
567
|
+
WHEN coalesce(
|
|
568
|
+
lease.resume_state #>> '{sessionState,workspaceArchive}', ''
|
|
569
|
+
) <> ''
|
|
570
|
+
OR coalesce(
|
|
571
|
+
lease.resume_state #>> '{sessionState,workspaceArchivePrev}', ''
|
|
572
|
+
) <> ''
|
|
573
|
+
THEN coalesce(lease.resume_backend_id, lease.backend)
|
|
574
|
+
ELSE null END,
|
|
575
|
+
data_plane_url = null,
|
|
576
|
+
terminal_data_plane_url = null,
|
|
577
|
+
provider_created_at = null,
|
|
578
|
+
provider_deadline_at = null,
|
|
579
|
+
rotation_requested_at = null,
|
|
580
|
+
rotation_reason = null,
|
|
581
|
+
updated_at = pg_catalog.now()
|
|
582
|
+
WHERE lease.id = ANY(locked_ids)
|
|
583
|
+
AND lease.liveness = 'warming'
|
|
584
|
+
AND lease.expires_at < pg_catalog.now()
|
|
585
|
+
AND lease.instance_id IS NULL
|
|
586
|
+
AND (
|
|
587
|
+
lease.reaper_hold_id IS NULL
|
|
588
|
+
OR lease.reaper_hold_until <= pg_catalog.now()
|
|
589
|
+
);
|
|
590
|
+
|
|
591
|
+
UPDATE %1$I.sandbox_leases lease SET
|
|
592
|
+
liveness = 'draining',
|
|
593
|
+
refcount = 0,
|
|
594
|
+
turn_holders = 0,
|
|
595
|
+
viewer_holders = 0,
|
|
596
|
+
data_plane_url = null,
|
|
597
|
+
terminal_data_plane_url = null,
|
|
598
|
+
lease_epoch = lease.lease_epoch + 1,
|
|
599
|
+
reaper_hold_id = null,
|
|
600
|
+
reaper_hold_until = null,
|
|
601
|
+
reaper_hold_reason = null,
|
|
602
|
+
expires_at = pg_catalog.now() - interval '1 millisecond',
|
|
603
|
+
updated_at = pg_catalog.now()
|
|
604
|
+
WHERE lease.id = ANY(locked_ids)
|
|
605
|
+
AND lease.liveness = 'warming'
|
|
606
|
+
AND lease.expires_at < pg_catalog.now()
|
|
607
|
+
AND lease.instance_id IS NOT NULL
|
|
608
|
+
AND (
|
|
609
|
+
lease.reaper_hold_id IS NULL
|
|
610
|
+
OR lease.reaper_hold_until <= pg_catalog.now()
|
|
611
|
+
);
|
|
612
|
+
|
|
613
|
+
RETURN QUERY
|
|
614
|
+
SELECT lease.workspace_id, lease.sandbox_group_id,
|
|
615
|
+
lease.instance_id, lease.lease_epoch
|
|
616
|
+
FROM %1$I.sandbox_leases lease
|
|
617
|
+
WHERE lease.id = ANY(locked_ids)
|
|
618
|
+
AND lease.liveness = 'draining'
|
|
619
|
+
AND lease.expires_at < pg_catalog.now()
|
|
620
|
+
AND lease.refcount = 0
|
|
621
|
+
AND (
|
|
622
|
+
lease.reaper_hold_id IS NULL
|
|
623
|
+
OR lease.reaper_hold_until <= pg_catalog.now()
|
|
624
|
+
);
|
|
625
|
+
END;
|
|
626
|
+
$function$;
|
|
627
|
+
$create$, data_schema);
|
|
628
|
+
END
|
|
629
|
+
$interaction_aware_reaper$;
|
|
630
|
+
|
|
631
|
+
REVOKE ALL ON FUNCTION opengeni_private.reap_sandbox_leases(
|
|
632
|
+
bigint, bigint, bigint, bigint
|
|
633
|
+
) FROM PUBLIC;
|
|
634
|
+
|
|
635
|
+
DO $reaper_grant$
|
|
636
|
+
BEGIN
|
|
637
|
+
IF EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'opengeni_app') THEN
|
|
638
|
+
GRANT EXECUTE ON FUNCTION opengeni_private.reap_sandbox_leases(
|
|
639
|
+
bigint, bigint, bigint, bigint
|
|
640
|
+
) TO opengeni_app;
|
|
641
|
+
END IF;
|
|
642
|
+
END
|
|
643
|
+
$reaper_grant$;
|
|
644
|
+
|
|
645
|
+
RESET statement_timeout;
|
|
646
|
+
RESET lock_timeout;
|