@tenetkit/pg 0.40.1 → 0.41.2
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/postgres/{event-stream.d.ts → events/event-stream.d.ts} +2 -2
- package/dist/postgres/{event-stream.js → events/event-stream.js} +2 -2
- package/dist/postgres/{transaction-events.d.ts → events/transaction-events.d.ts} +2 -2
- package/dist/postgres/{transaction-events.js → events/transaction-events.js} +4 -4
- package/dist/postgres/run-schema.js +6 -6
- package/dist/postgres/{claims.d.ts → runs/claims.d.ts} +2 -2
- package/dist/postgres/{claims.js → runs/claims.js} +1 -1
- package/dist/postgres/{locks.d.ts → runs/locks.d.ts} +1 -1
- package/dist/postgres/{locks.js → runs/locks.js} +2 -2
- package/dist/postgres/runtime-layer.d.ts +4 -5
- package/dist/postgres/runtime-layer.js +9 -9
- package/dist/postgres/{session-cancellation.js → sessions/session-cancellation.js} +1 -1
- package/dist/postgres/{session-storage.d.ts → sessions/session-storage.d.ts} +4 -3
- package/dist/postgres/{session-storage.js → sessions/session-storage.js} +1 -1
- package/dist/postgres/{session-store.d.ts → sessions/session-store.d.ts} +5 -5
- package/dist/postgres/{session-store.js → sessions/session-store.js} +46 -40
- package/dist/postgres/{store-admit.d.ts → store/admit.d.ts} +2 -2
- package/dist/postgres/{store-admit.js → store/admit.js} +6 -6
- package/dist/postgres/{store-cancel.d.ts → store/cancel.d.ts} +1 -1
- package/dist/postgres/{store-cancel.js → store/cancel.js} +42 -46
- package/dist/postgres/{store-claims.d.ts → store/claims.d.ts} +3 -3
- package/dist/postgres/{store-claims.js → store/claims.js} +9 -7
- package/dist/postgres/{store-fan-out.d.ts → store/fan-out.d.ts} +2 -2
- package/dist/postgres/{store-fan-out.js → store/fan-out.js} +2 -2
- package/dist/postgres/{store.d.ts → store/index.d.ts} +7 -4
- package/dist/postgres/{store.js → store/index.js} +56 -54
- package/dist/postgres/{store-inspection.d.ts → store/inspection.d.ts} +3 -3
- package/dist/postgres/{store-inspection.js → store/inspection.js} +10 -10
- package/dist/postgres/{store-messaging.d.ts → store/messaging.d.ts} +2 -2
- package/dist/postgres/{store-messaging.js → store/messaging.js} +1 -1
- package/dist/postgres/{store-model-response.d.ts → store/model-response.d.ts} +4 -4
- package/dist/postgres/{store-model-response.js → store/model-response.js} +46 -38
- package/dist/postgres/{store-ops.d.ts → store/ops.d.ts} +4 -4
- package/dist/postgres/{store-ops.js → store/ops.js} +102 -94
- package/dist/postgres/{store-program.d.ts → store/program.d.ts} +2 -2
- package/dist/postgres/{store-program.js → store/program.js} +5 -5
- package/dist/postgres/{pg-helpers.d.ts → store/runtime.d.ts} +18 -12
- package/dist/postgres/{pg-helpers.js → store/runtime.js} +49 -48
- package/dist/postgres/{store-suspend.d.ts → store/suspend.d.ts} +1 -1
- package/dist/postgres/{store-suspend.js → store/suspend.js} +14 -14
- package/package.json +2 -2
- /package/dist/postgres/{session-cancellation.d.ts → sessions/session-cancellation.d.ts} +0 -0
|
@@ -3,10 +3,10 @@ import type { PgClient } from "@effect/sql-pg";
|
|
|
3
3
|
import { SqlClient } from "effect/unstable/sql";
|
|
4
4
|
import type { SqlError } from "effect/unstable/sql/SqlError";
|
|
5
5
|
import { RunNotFound, RuntimeUnavailable } from "tenetkit/runtime/driver/errors";
|
|
6
|
-
import type { Interface as RunStoreInterface } from "tenetkit/runtime/driver/run
|
|
7
|
-
import type { DecodedRun } from "tenetkit/runtime/driver/sql/rows";
|
|
6
|
+
import type { Interface as RunStoreInterface } from "tenetkit/runtime/driver/run/store";
|
|
7
|
+
import type { DecodedRun } from "tenetkit/runtime/driver/sql/codec/rows";
|
|
8
8
|
import type { EventHub } from "tenetkit/runtime/driver/sql/subscribers";
|
|
9
|
-
import type { WithoutSqlError } from "tenetkit/runtime/driver/sql/
|
|
9
|
+
import type { WithoutSqlError } from "tenetkit/runtime/driver/sql/effect";
|
|
10
10
|
type SqlR = SqlClient.SqlClient | PgClient.PgClient;
|
|
11
11
|
export type RunFn = <A, E>(effect: Effect.Effect<A, E | SqlError, SqlR>) => Effect.Effect<A, WithoutSqlError<E | SqlError> | RuntimeUnavailable>;
|
|
12
12
|
export declare const postgresOperations: (input: {
|
|
@@ -15,7 +15,7 @@ export declare const postgresOperations: (input: {
|
|
|
15
15
|
readonly run: RunFn;
|
|
16
16
|
readonly runNoTxn: RunFn;
|
|
17
17
|
readonly requireRun: (runId: string) => Effect.Effect<DecodedRun, RunNotFound | RuntimeUnavailable | SqlError, SqlR>;
|
|
18
|
-
readonly requireClaim: (claim: import("tenetkit/runtime/driver/run
|
|
18
|
+
readonly requireClaim: (claim: import("tenetkit/runtime/driver/run/store").ExecutionClaim) => Effect.Effect<void, import("tenetkit/runtime/driver/sql/errors").StaleClaim | RunNotFound | RuntimeUnavailable | SqlError, SqlR>;
|
|
19
19
|
readonly nextId: (prefix: string) => Effect.Effect<string>;
|
|
20
20
|
}) => Pick<RunStoreInterface, "recordOperation" | "startOperation" | "completeOperation" | "commitModelResponse" | "commitInterruptedModelResponse" | "expireRunningOperation" | "recoverRunningOperations" | "getOperation" | "getOperationByKey" | "operationCancellations" | "acknowledgeOperationCancellation" | "resolveOperation">;
|
|
21
21
|
export {};
|
|
@@ -1,21 +1,26 @@
|
|
|
1
1
|
import { Effect, Schema } from "effect";
|
|
2
2
|
import { SqlClient } from "effect/unstable/sql";
|
|
3
3
|
import { OperationResolutionConflict, RunNotFound, RunTerminal, RuntimeUnavailable, } from "tenetkit/runtime/driver/errors";
|
|
4
|
-
import { OperationResolution, digest as resolutionDigest } from "tenetkit/runtime/driver/operation
|
|
4
|
+
import { OperationResolution, digest as resolutionDigest } from "tenetkit/runtime/driver/operation/resolution";
|
|
5
5
|
import { isTerminal } from "tenetkit/runtime/driver/run";
|
|
6
|
-
import { ExecutionCheckpoint } from "tenetkit/runtime/driver/execution
|
|
7
|
-
import { decodeJson, encodeExecutableRef, encodeJson, encodeJsonValue } from "tenetkit/runtime/driver/sql/codecs";
|
|
6
|
+
import { ExecutionCheckpoint } from "tenetkit/runtime/driver/execution/state";
|
|
7
|
+
import { decodeJson, encodeExecutableRef, encodeJson, encodeJsonValue } from "tenetkit/runtime/driver/sql/codec/codecs";
|
|
8
8
|
import { canBlindRetry } from "tenetkit/runtime/driver/sql/operations";
|
|
9
|
-
import { appendEvent, toOperationRecord } from "./
|
|
10
|
-
import { encodeContinuation } from "tenetkit/runtime/driver/steering";
|
|
11
|
-
import { checkpointRef } from "tenetkit/runtime/driver/executable
|
|
12
|
-
import { getProgramOperation, resolveProgramOperation } from "tenetkit/runtime/driver/sql/store
|
|
13
|
-
import { settleAdmittedCancellation } from "tenetkit/runtime/driver/sql/store
|
|
14
|
-
import { acknowledgeOperationCancellation, operationCancellations } from "tenetkit/runtime/driver/sql/store
|
|
15
|
-
import { postgresModelResponseOperations } from "./
|
|
16
|
-
import { appendHandoffSessionEntry, verifyHandoffSessionEntry } from "
|
|
17
|
-
import { handoffSessionEntry, isHandoffCommit, sameHandoffCheckpoint, sameHandoffCommit, } from "tenetkit/runtime/driver/handoff
|
|
18
|
-
import { lockRunHierarchy } from "
|
|
9
|
+
import { appendEvent, toOperationRecord } from "./runtime.js";
|
|
10
|
+
import { encodeContinuation } from "tenetkit/runtime/driver/run/steering";
|
|
11
|
+
import { checkpointRef } from "tenetkit/runtime/driver/executable/manifest";
|
|
12
|
+
import { getProgramOperation, resolveProgramOperation } from "tenetkit/runtime/driver/sql/store/program";
|
|
13
|
+
import { settleAdmittedCancellation } from "tenetkit/runtime/driver/sql/store/control";
|
|
14
|
+
import { acknowledgeOperationCancellation, operationCancellations, } from "tenetkit/runtime/driver/sql/store/operation/operations";
|
|
15
|
+
import { postgresModelResponseOperations } from "./model-response.js";
|
|
16
|
+
import { appendHandoffSessionEntry, verifyHandoffSessionEntry } from "../sessions/session-store.js";
|
|
17
|
+
import { handoffSessionEntry, isHandoffCommit, sameHandoffCheckpoint, sameHandoffCommit, } from "tenetkit/runtime/driver/session/handoff";
|
|
18
|
+
import { lockRunHierarchy } from "../runs/locks.js";
|
|
19
|
+
const isCompletedOperationStatus = (status) => status === "cancelling" ||
|
|
20
|
+
status === "cancelled" ||
|
|
21
|
+
status === "succeeded" ||
|
|
22
|
+
status === "failed" ||
|
|
23
|
+
status === "unknown";
|
|
19
24
|
export const postgresOperations = (input) => {
|
|
20
25
|
const { sql, hub, run, runNoTxn, requireRun, requireClaim, nextId } = input;
|
|
21
26
|
const fenced = (claim, effect) => run(sql `SELECT run_id FROM tenetkit_runs WHERE run_id = ${claim.runId} FOR UPDATE`.pipe(Effect.andThen(requireClaim(claim)), Effect.andThen(effect)));
|
|
@@ -51,6 +56,82 @@ export const postgresOperations = (input) => {
|
|
|
51
56
|
`;
|
|
52
57
|
return { record: toOperationRecord(next[0]), outcome: "unknown" };
|
|
53
58
|
});
|
|
59
|
+
const existingOperation = (op, prior) => Effect.gen(function* () {
|
|
60
|
+
const consumed = yield* sql `
|
|
61
|
+
SELECT entry_id FROM tenetkit_run_steering
|
|
62
|
+
WHERE run_id = ${op.runId} AND consumed_operation_id = ${prior.operation_id}
|
|
63
|
+
ORDER BY sequence
|
|
64
|
+
`;
|
|
65
|
+
const retried = op.steeringEntryIds ?? [];
|
|
66
|
+
if (consumed.length !== retried.length || consumed.some((entry, index) => entry.entry_id !== retried[index])) {
|
|
67
|
+
return yield* RuntimeUnavailable.make({ message: "steering consumption does not match operation" });
|
|
68
|
+
}
|
|
69
|
+
return toOperationRecord(prior);
|
|
70
|
+
});
|
|
71
|
+
const verifyPendingSteering = (op) => Effect.gen(function* () {
|
|
72
|
+
const steeringEntryIds = op.steeringEntryIds ?? [];
|
|
73
|
+
const pending = yield* sql `
|
|
74
|
+
SELECT entry_id FROM tenetkit_run_steering
|
|
75
|
+
WHERE run_id = ${op.runId} AND consumed_operation_id IS NULL AND discarded_reason IS NULL
|
|
76
|
+
ORDER BY sequence
|
|
77
|
+
`;
|
|
78
|
+
const selected = pending.slice(0, steeringEntryIds.length);
|
|
79
|
+
if (selected.length !== steeringEntryIds.length ||
|
|
80
|
+
selected.some((entry, index) => entry.entry_id !== steeringEntryIds[index])) {
|
|
81
|
+
return yield* RuntimeUnavailable.make({ message: "steering entries are not the pending prefix" });
|
|
82
|
+
}
|
|
83
|
+
return steeringEntryIds;
|
|
84
|
+
});
|
|
85
|
+
const verifyCompletedOperation = (op, loaded, row) => Effect.gen(function* () {
|
|
86
|
+
const current = toOperationRecord(row);
|
|
87
|
+
if (current.kind === "handoff" && current.status === "succeeded" && isHandoffCommit(current.result)) {
|
|
88
|
+
if (op.outcome._tag !== "Succeeded" ||
|
|
89
|
+
!sameHandoffCommit(current.result, op.outcome.value) ||
|
|
90
|
+
!sameHandoffCheckpoint(loaded.driverCheckpoint, op.checkpoint)) {
|
|
91
|
+
return yield* RuntimeUnavailable.make({ message: "handoff operation has a divergent completion retry" });
|
|
92
|
+
}
|
|
93
|
+
const entry = handoffSessionEntry({
|
|
94
|
+
sessionId: loaded.message.sessionId,
|
|
95
|
+
operationKey: current.operationKey,
|
|
96
|
+
value: op.outcome.value,
|
|
97
|
+
});
|
|
98
|
+
if (Schema.is(RuntimeUnavailable)(entry))
|
|
99
|
+
return yield* entry;
|
|
100
|
+
yield* verifyHandoffSessionEntry(entry).pipe(Effect.mapError((error) => RuntimeUnavailable.make({ message: error.message })));
|
|
101
|
+
}
|
|
102
|
+
return current;
|
|
103
|
+
});
|
|
104
|
+
const verifyOperationSteering = (op) => Effect.gen(function* () {
|
|
105
|
+
for (const entryId of new Set(op.steeringEntryIds ?? [])) {
|
|
106
|
+
const rows = yield* sql `
|
|
107
|
+
SELECT consumed_operation_id FROM tenetkit_run_steering
|
|
108
|
+
WHERE run_id = ${op.runId} AND entry_id = ${entryId}
|
|
109
|
+
`;
|
|
110
|
+
if (rows[0]?.consumed_operation_id !== op.operationId) {
|
|
111
|
+
return yield* RuntimeUnavailable.make({ message: `steering entry ${entryId} does not belong to operation` });
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
const persistOperationOutcome = (op) => {
|
|
116
|
+
if (op.outcome._tag === "Succeeded") {
|
|
117
|
+
return sql `
|
|
118
|
+
UPDATE tenetkit_run_operations
|
|
119
|
+
SET status = 'succeeded', result_json = ${encodeJsonValue(op.outcome.value)}, finished_at = NOW()
|
|
120
|
+
WHERE run_id = ${op.runId} AND operation_id = ${op.operationId} AND status IN ('requested', 'running')
|
|
121
|
+
`;
|
|
122
|
+
}
|
|
123
|
+
if (op.outcome._tag === "Failed") {
|
|
124
|
+
return sql `
|
|
125
|
+
UPDATE tenetkit_run_operations
|
|
126
|
+
SET status = 'failed', error_json = ${encodeJsonValue(op.outcome.error)}, finished_at = NOW()
|
|
127
|
+
WHERE run_id = ${op.runId} AND operation_id = ${op.operationId} AND status IN ('requested', 'running')
|
|
128
|
+
`;
|
|
129
|
+
}
|
|
130
|
+
return sql `
|
|
131
|
+
UPDATE tenetkit_run_operations SET status = 'unknown', finished_at = NOW()
|
|
132
|
+
WHERE run_id = ${op.runId} AND operation_id = ${op.operationId} AND status IN ('requested', 'running')
|
|
133
|
+
`;
|
|
134
|
+
};
|
|
54
135
|
return {
|
|
55
136
|
recordOperation: (op) => fenced(op, Effect.gen(function* () {
|
|
56
137
|
const loaded = yield* requireRun(op.runId);
|
|
@@ -62,33 +143,12 @@ export const postgresOperations = (input) => {
|
|
|
62
143
|
WHERE run_id = ${op.runId} AND operation_key = ${op.operationKey}
|
|
63
144
|
`;
|
|
64
145
|
const prior = existing[0];
|
|
65
|
-
if (prior !== undefined)
|
|
66
|
-
|
|
67
|
-
SELECT entry_id FROM tenetkit_run_steering
|
|
68
|
-
WHERE run_id = ${op.runId} AND consumed_operation_id = ${prior.operation_id}
|
|
69
|
-
ORDER BY sequence
|
|
70
|
-
`;
|
|
71
|
-
const retried = op.steeringEntryIds ?? [];
|
|
72
|
-
if (consumed.length !== retried.length ||
|
|
73
|
-
consumed.some((entry, index) => entry.entry_id !== retried[index])) {
|
|
74
|
-
return yield* RuntimeUnavailable.make({ message: "steering consumption does not match operation" });
|
|
75
|
-
}
|
|
76
|
-
return toOperationRecord(prior);
|
|
77
|
-
}
|
|
146
|
+
if (prior !== undefined)
|
|
147
|
+
return yield* existingOperation(op, prior);
|
|
78
148
|
if (loaded.cancellationRequested) {
|
|
79
149
|
return yield* RuntimeUnavailable.make({ message: `run ${loaded.runId} is cancelling` });
|
|
80
150
|
}
|
|
81
|
-
const steeringEntryIds = op
|
|
82
|
-
const pending = yield* sql `
|
|
83
|
-
SELECT entry_id FROM tenetkit_run_steering
|
|
84
|
-
WHERE run_id = ${op.runId} AND consumed_operation_id IS NULL AND discarded_reason IS NULL
|
|
85
|
-
ORDER BY sequence
|
|
86
|
-
`;
|
|
87
|
-
const selected = pending.slice(0, steeringEntryIds.length);
|
|
88
|
-
if (selected.length !== steeringEntryIds.length ||
|
|
89
|
-
selected.some((entry, index) => entry.entry_id !== steeringEntryIds[index])) {
|
|
90
|
-
return yield* RuntimeUnavailable.make({ message: "steering entries are not the pending prefix" });
|
|
91
|
-
}
|
|
151
|
+
const steeringEntryIds = yield* verifyPendingSteering(op);
|
|
92
152
|
const operationId = yield* nextId("op");
|
|
93
153
|
const executableRef = yield* Effect.try({
|
|
94
154
|
try: () => checkpointRef(loaded.executableRef, loaded.executableManifest, op.checkpoint),
|
|
@@ -165,40 +225,10 @@ export const postgresOperations = (input) => {
|
|
|
165
225
|
const row = existing[0];
|
|
166
226
|
if (row === undefined)
|
|
167
227
|
return yield* RuntimeUnavailable.make({ message: "operation missing" });
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
row.status === "cancelled" ||
|
|
171
|
-
row.status === "succeeded" ||
|
|
172
|
-
row.status === "failed" ||
|
|
173
|
-
row.status === "unknown") {
|
|
174
|
-
if (current.kind === "handoff" && current.status === "succeeded" && isHandoffCommit(current.result)) {
|
|
175
|
-
if (op.outcome._tag !== "Succeeded" ||
|
|
176
|
-
!sameHandoffCommit(current.result, op.outcome.value) ||
|
|
177
|
-
!sameHandoffCheckpoint(loaded.driverCheckpoint, op.checkpoint)) {
|
|
178
|
-
return yield* RuntimeUnavailable.make({ message: "handoff operation has a divergent completion retry" });
|
|
179
|
-
}
|
|
180
|
-
const entry = handoffSessionEntry({
|
|
181
|
-
sessionId: loaded.message.sessionId,
|
|
182
|
-
operationKey: current.operationKey,
|
|
183
|
-
value: op.outcome.value,
|
|
184
|
-
});
|
|
185
|
-
if (Schema.is(RuntimeUnavailable)(entry))
|
|
186
|
-
return yield* entry;
|
|
187
|
-
yield* verifyHandoffSessionEntry(entry).pipe(Effect.mapError((error) => RuntimeUnavailable.make({ message: error.message })));
|
|
188
|
-
}
|
|
189
|
-
return current;
|
|
190
|
-
}
|
|
191
|
-
for (const entryId of new Set(op.steeringEntryIds ?? [])) {
|
|
192
|
-
const rows = yield* sql `
|
|
193
|
-
SELECT consumed_operation_id FROM tenetkit_run_steering
|
|
194
|
-
WHERE run_id = ${op.runId} AND entry_id = ${entryId}
|
|
195
|
-
`;
|
|
196
|
-
if (rows[0]?.consumed_operation_id !== op.operationId) {
|
|
197
|
-
return yield* RuntimeUnavailable.make({
|
|
198
|
-
message: `steering entry ${entryId} does not belong to operation`,
|
|
199
|
-
});
|
|
200
|
-
}
|
|
228
|
+
if (isCompletedOperationStatus(row.status)) {
|
|
229
|
+
return yield* verifyCompletedOperation(op, loaded, row);
|
|
201
230
|
}
|
|
231
|
+
yield* verifyOperationSteering(op);
|
|
202
232
|
const executableRef = yield* Effect.try({
|
|
203
233
|
try: () => checkpointRef(loaded.executableRef, loaded.executableManifest, op.checkpoint),
|
|
204
234
|
catch: (error) => RuntimeUnavailable.make({ message: String(error) }),
|
|
@@ -213,29 +243,7 @@ export const postgresOperations = (input) => {
|
|
|
213
243
|
return yield* entry;
|
|
214
244
|
yield* appendHandoffSessionEntry(entry).pipe(Effect.mapError((error) => RuntimeUnavailable.make({ message: error.message })));
|
|
215
245
|
}
|
|
216
|
-
|
|
217
|
-
yield* sql `
|
|
218
|
-
UPDATE tenetkit_run_operations
|
|
219
|
-
SET status = 'succeeded', result_json = ${encodeJsonValue(op.outcome.value)}, finished_at = NOW()
|
|
220
|
-
WHERE run_id = ${op.runId} AND operation_id = ${op.operationId}
|
|
221
|
-
AND status IN ('requested', 'running')
|
|
222
|
-
`;
|
|
223
|
-
}
|
|
224
|
-
else if (op.outcome._tag === "Failed") {
|
|
225
|
-
yield* sql `
|
|
226
|
-
UPDATE tenetkit_run_operations
|
|
227
|
-
SET status = 'failed', error_json = ${encodeJsonValue(op.outcome.error)}, finished_at = NOW()
|
|
228
|
-
WHERE run_id = ${op.runId} AND operation_id = ${op.operationId}
|
|
229
|
-
AND status IN ('requested', 'running')
|
|
230
|
-
`;
|
|
231
|
-
}
|
|
232
|
-
else {
|
|
233
|
-
yield* sql `
|
|
234
|
-
UPDATE tenetkit_run_operations SET status = 'unknown', finished_at = NOW()
|
|
235
|
-
WHERE run_id = ${op.runId} AND operation_id = ${op.operationId}
|
|
236
|
-
AND status IN ('requested', 'running')
|
|
237
|
-
`;
|
|
238
|
-
}
|
|
246
|
+
yield* persistOperationOutcome(op);
|
|
239
247
|
yield* sql `
|
|
240
248
|
UPDATE tenetkit_runs SET
|
|
241
249
|
driver_checkpoint_json = COALESCE(${op.checkpoint === undefined ? null : encodeJson(ExecutionCheckpoint, op.checkpoint)}, driver_checkpoint_json),
|
|
@@ -348,7 +356,7 @@ export const postgresOperations = (input) => {
|
|
|
348
356
|
SELECT COUNT(*)::int AS unresolved FROM tenetkit_run_operations
|
|
349
357
|
WHERE run_id = ${op.runId} AND status = 'unknown'
|
|
350
358
|
`;
|
|
351
|
-
const runStatus =
|
|
359
|
+
const runStatus = (unresolved[0]?.unresolved ?? 0) > 0
|
|
352
360
|
? sql `'needs-resolution'`
|
|
353
361
|
: sql `CASE WHEN cancellation_requested THEN 'cancelling' ELSE 'queued' END`;
|
|
354
362
|
yield* sql `
|
|
@@ -2,9 +2,9 @@ import { Effect } from "effect";
|
|
|
2
2
|
import type { PgClient } from "@effect/sql-pg";
|
|
3
3
|
import { SqlClient } from "effect/unstable/sql";
|
|
4
4
|
import { RuntimeUnavailable } from "tenetkit/runtime/driver/errors";
|
|
5
|
-
import type { Interface as RunStore } from "tenetkit/runtime/driver/run
|
|
5
|
+
import type { Interface as RunStore } from "tenetkit/runtime/driver/run/store";
|
|
6
6
|
import type { EventHub } from "tenetkit/runtime/driver/sql/subscribers";
|
|
7
|
-
import type { WithoutSqlError } from "tenetkit/runtime/driver/sql/
|
|
7
|
+
import type { WithoutSqlError } from "tenetkit/runtime/driver/sql/effect";
|
|
8
8
|
import type { SqlError } from "effect/unstable/sql/SqlError";
|
|
9
9
|
type SqlR = SqlClient.SqlClient | PgClient.PgClient;
|
|
10
10
|
export type Run = <A, E>(effect: Effect.Effect<A, E | SqlError, SqlR>) => Effect.Effect<A, WithoutSqlError<E | SqlError> | RuntimeUnavailable>;
|
|
@@ -2,11 +2,11 @@ import { Effect } from "effect";
|
|
|
2
2
|
import { ProgramCapabilities } from "tenetkit";
|
|
3
3
|
import { SqlClient } from "effect/unstable/sql";
|
|
4
4
|
import { RuntimeUnavailable } from "tenetkit/runtime/driver/errors";
|
|
5
|
-
import { requireExecutionClaim } from "tenetkit/runtime/driver/sql/store
|
|
6
|
-
import { loadProgramState, getProgramOperation, reserveProgramOperation, admitProgramAgents, commitProgramLog, settleProgramOperation, suspendProgramOperation, startProgramOperation, } from "tenetkit/runtime/driver/sql/store
|
|
7
|
-
import { completeRun, requireRun } from "./
|
|
8
|
-
import { suspend } from "./
|
|
9
|
-
import { admitProgramChild } from "tenetkit/runtime/driver/sql/store
|
|
5
|
+
import { requireExecutionClaim } from "tenetkit/runtime/driver/sql/store/execution";
|
|
6
|
+
import { loadProgramState, getProgramOperation, reserveProgramOperation, admitProgramAgents, commitProgramLog, settleProgramOperation, suspendProgramOperation, startProgramOperation, } from "tenetkit/runtime/driver/sql/store/program";
|
|
7
|
+
import { completeRun, requireRun } from "./runtime.js";
|
|
8
|
+
import { suspend } from "./suspend.js";
|
|
9
|
+
import { admitProgramChild } from "tenetkit/runtime/driver/sql/store/admit";
|
|
10
10
|
export const programStoreMethods = (input) => {
|
|
11
11
|
const fenced = (claim, effect) => input.run(input.sql `SELECT run_id FROM tenetkit_runs WHERE run_id = ${claim.runId} FOR UPDATE`.pipe(Effect.andThen(requireExecutionClaim(claim)), Effect.andThen(effect)));
|
|
12
12
|
return {
|
|
@@ -2,16 +2,16 @@ import { Effect } from "effect";
|
|
|
2
2
|
import { SqlClient } from "effect/unstable/sql";
|
|
3
3
|
import type { SqlError } from "effect/unstable/sql/SqlError";
|
|
4
4
|
import { PgClient } from "@effect/sql-pg";
|
|
5
|
-
import { type RunEvent } from "tenetkit/runtime/driver/run
|
|
6
|
-
import type { ExecutableManifest, ExecutableRef } from "tenetkit/runtime/driver/executable
|
|
7
|
-
import type { Message } from "tenetkit/runtime/driver/message";
|
|
5
|
+
import { type RunEvent } from "tenetkit/runtime/driver/run/event";
|
|
6
|
+
import type { ExecutableManifest, ExecutableRef } from "tenetkit/runtime/driver/executable/manifest";
|
|
7
|
+
import type { Message } from "tenetkit/runtime/driver/messaging/message";
|
|
8
8
|
import { type RunStatus } from "tenetkit/runtime/driver/run";
|
|
9
|
-
import { decodeMessage, decodeQueue, encodeQueue } from "tenetkit/runtime/driver/sql/codecs";
|
|
9
|
+
import { decodeMessage, decodeQueue, encodeQueue } from "tenetkit/runtime/driver/sql/codec/codecs";
|
|
10
10
|
import type { EventHub } from "tenetkit/runtime/driver/sql/subscribers";
|
|
11
|
-
import type { DecodedRun } from "tenetkit/runtime/driver/sql/rows";
|
|
12
|
-
import type { EmittableAgentLoopEvent } from "tenetkit/runtime/driver/agent
|
|
13
|
-
import { type ExecutionClaim } from "tenetkit/runtime/driver/run
|
|
14
|
-
import type { ExecutionResult } from "tenetkit/runtime/driver/execution
|
|
11
|
+
import type { DecodedRun } from "tenetkit/runtime/driver/sql/codec/rows";
|
|
12
|
+
import type { EmittableAgentLoopEvent } from "tenetkit/runtime/driver/execution/agent/event";
|
|
13
|
+
import { type ExecutionClaim } from "tenetkit/runtime/driver/run/store";
|
|
14
|
+
import type { ExecutionResult } from "tenetkit/runtime/driver/execution/state";
|
|
15
15
|
import { RunNotFound, RunTerminal, RuntimeUnavailable } from "tenetkit/runtime/driver/errors";
|
|
16
16
|
import { StaleClaim } from "tenetkit/runtime/driver/sql/errors";
|
|
17
17
|
type StoreError = RuntimeUnavailable | SqlError;
|
|
@@ -26,9 +26,14 @@ type AgentEventError = RunNotFound | RunTerminal | StoreError | StaleClaim;
|
|
|
26
26
|
type AgentEventEffect = Effect.Effect<undefined, AgentEventError, SqlClient.SqlClient>;
|
|
27
27
|
type CompleteRunEffect = Effect.Effect<undefined, RunTerminal | StoreError, SqlClient.SqlClient>;
|
|
28
28
|
type SettleParentEffect = Effect.Effect<void, StoreError, SqlClient.SqlClient | PgClient.PgClient>;
|
|
29
|
-
|
|
29
|
+
type EventField = RunEvent extends RunEvent ? unknown : never;
|
|
30
|
+
type AppendInput = object & {
|
|
30
31
|
readonly _tag: string;
|
|
31
|
-
}
|
|
32
|
+
};
|
|
33
|
+
export interface EventPartial {
|
|
34
|
+
readonly _tag: string;
|
|
35
|
+
readonly [key: string]: EventField;
|
|
36
|
+
}
|
|
32
37
|
export declare const loadRun: (runId: string) => Effect.Effect<DecodedRun | undefined, RuntimeUnavailable | SqlError, SqlClient.SqlClient>;
|
|
33
38
|
export declare const requireRun: (runId: string) => Effect.Effect<DecodedRun, RunNotFound | RuntimeUnavailable | SqlError, SqlClient.SqlClient>;
|
|
34
39
|
export declare const emitAgentEvent: {
|
|
@@ -45,7 +50,8 @@ export declare const loadEventsAfter: {
|
|
|
45
50
|
};
|
|
46
51
|
export declare const allocateSequence: (runId: string) => Effect.Effect<number, SqlError, SqlClient.SqlClient>;
|
|
47
52
|
export declare const appendEvent: {
|
|
48
|
-
(run: DecodedRun, partial:
|
|
53
|
+
<Partial extends AppendInput>(run: DecodedRun, partial: Partial, nextStatus?: RunStatus): (hub: EventHub) => RunEventEffect;
|
|
54
|
+
<Partial extends AppendInput>(hub: EventHub, run: DecodedRun, partial: Partial, nextStatus?: RunStatus): RunEventEffect;
|
|
49
55
|
(hub: EventHub, run: DecodedRun, partial: EventPartial, nextStatus?: RunStatus): RunEventEffect;
|
|
50
56
|
};
|
|
51
57
|
export declare const promoteHead: {
|
|
@@ -77,7 +83,7 @@ export declare const insertRun: (input: {
|
|
|
77
83
|
readonly executableManifest: ExecutableManifest;
|
|
78
84
|
readonly rootRunId: string;
|
|
79
85
|
readonly depth: number;
|
|
80
|
-
readonly treePolicy: import("tenetkit/runtime/driver/tree
|
|
86
|
+
readonly treePolicy: import("tenetkit/runtime/driver/tree/policy").TreePolicy;
|
|
81
87
|
readonly parentRunId?: string;
|
|
82
88
|
readonly invocationId?: string;
|
|
83
89
|
readonly acceptedSequence: number;
|
|
@@ -1,19 +1,37 @@
|
|
|
1
1
|
import { Effect, Function } from "effect";
|
|
2
2
|
import { SqlClient } from "effect/unstable/sql";
|
|
3
3
|
import { PgClient } from "@effect/sql-pg";
|
|
4
|
-
import { eventIdFor } from "tenetkit/runtime/driver/run
|
|
4
|
+
import { eventIdFor } from "tenetkit/runtime/driver/run/event";
|
|
5
5
|
import { isTerminal } from "tenetkit/runtime/driver/run";
|
|
6
|
-
import { StringArray, decodeMessage, decodeQueue, encodeExecutableManifest, encodeExecutableRef, encodeEvent, encodeJson, encodeMessage, encodeQueue, } from "tenetkit/runtime/driver/sql/codecs";
|
|
7
|
-
import { reconcileFanOutWith } from "tenetkit/runtime/driver/sql/store
|
|
8
|
-
import { decodePersistedEvents, decodeRunEffect, nowIso } from "tenetkit/runtime/driver/sql/store
|
|
9
|
-
import { NOTIFY_CHANNEL } from "
|
|
10
|
-
import { PendingRunOutcome } from "tenetkit/runtime/driver/run
|
|
6
|
+
import { StringArray, decodeMessage, decodeEvent, decodeQueue, encodeExecutableManifest, encodeExecutableRef, encodeEvent, encodeJson, encodeMessage, encodeQueue, } from "tenetkit/runtime/driver/sql/codec/codecs";
|
|
7
|
+
import { reconcileFanOutWith } from "tenetkit/runtime/driver/sql/store/fan-out/service";
|
|
8
|
+
import { decodePersistedEvents, decodeRunEffect, nowIso } from "tenetkit/runtime/driver/sql/store/statements";
|
|
9
|
+
import { NOTIFY_CHANNEL } from "../schema.js";
|
|
10
|
+
import { PendingRunOutcome } from "tenetkit/runtime/driver/run/store";
|
|
11
11
|
import { RunNotFound, RunTerminal, RuntimeUnavailable } from "tenetkit/runtime/driver/errors";
|
|
12
12
|
import { StaleClaim } from "tenetkit/runtime/driver/sql/errors";
|
|
13
13
|
import { admitChildSettlementFromEventId } from "tenetkit/runtime/driver/sql/settlement-notifications";
|
|
14
|
-
import { discardPendingSteering } from "tenetkit/runtime/driver/sql/store
|
|
15
|
-
import { hasPendingOperationCancellation, hasUnsettledChild, loadTerminalEvent, reconcileChildWaitWith, } from "tenetkit/runtime/driver/sql/store
|
|
16
|
-
import { appendTerminalToolResultsForEvent } from "tenetkit/runtime/driver/sql/session
|
|
14
|
+
import { discardPendingSteering } from "tenetkit/runtime/driver/sql/store/steering/disposition";
|
|
15
|
+
import { hasPendingOperationCancellation, hasUnsettledChild, loadTerminalEvent, reconcileChildWaitWith, } from "tenetkit/runtime/driver/sql/store/child/settlement";
|
|
16
|
+
import { appendTerminalToolResultsForEvent } from "tenetkit/runtime/driver/sql/session/terminalization";
|
|
17
|
+
const isTerminalEvent = (event) => event._tag === "RunCompleted" || event._tag === "RunFailed" || event._tag === "RunCancelled";
|
|
18
|
+
const makeEvent = (run, partial, sequence, occurredAt) => {
|
|
19
|
+
const base = {
|
|
20
|
+
specVersion: "1",
|
|
21
|
+
eventId: eventIdFor(run.runId, sequence),
|
|
22
|
+
runId: run.runId,
|
|
23
|
+
sequence,
|
|
24
|
+
executableRef: run.executableRef,
|
|
25
|
+
rootRunId: run.rootRunId,
|
|
26
|
+
depth: run.depth,
|
|
27
|
+
occurredAt,
|
|
28
|
+
};
|
|
29
|
+
Object.assign(base, run.parentRunId === undefined ? {} : { parentRunId: run.parentRunId });
|
|
30
|
+
Object.assign(base, run.message.causationId === undefined ? {} : { causationId: run.message.causationId });
|
|
31
|
+
Object.assign(base, run.message.correlationId === undefined ? {} : { correlationId: run.message.correlationId });
|
|
32
|
+
Object.assign(base, run.attempt > 0 ? { attemptId: `${run.runId}:attempt:${run.attempt}` } : {});
|
|
33
|
+
return decodeEvent(JSON.stringify(Object.assign(base, partial)));
|
|
34
|
+
};
|
|
17
35
|
export const loadRun = (runId) => Effect.gen(function* () {
|
|
18
36
|
const sql = yield* SqlClient.SqlClient;
|
|
19
37
|
const rows = yield* sql `SELECT * FROM tenetkit_runs WHERE run_id = ${runId}`;
|
|
@@ -61,7 +79,7 @@ export const allocateSequence = (runId) => Effect.gen(function* () {
|
|
|
61
79
|
WHERE run_id = ${runId}
|
|
62
80
|
RETURNING last_sequence
|
|
63
81
|
`;
|
|
64
|
-
return
|
|
82
|
+
return rows[0].last_sequence;
|
|
65
83
|
});
|
|
66
84
|
export const appendEvent = Function.dual((args) => args.length >= 4 || (args.length === 3 && !("runId" in args[0])), (_hub, run, partial, nextStatus) => Effect.gen(function* () {
|
|
67
85
|
const sql = yield* SqlClient.SqlClient;
|
|
@@ -74,21 +92,7 @@ export const appendEvent = Function.dual((args) => args.length >= 4 || (args.len
|
|
|
74
92
|
yield* appendTerminalToolResultsForEvent({ run, event: partial });
|
|
75
93
|
const sequence = yield* allocateSequence(run.runId);
|
|
76
94
|
const occurredAt = yield* nowIso;
|
|
77
|
-
const event =
|
|
78
|
-
specVersion: "1",
|
|
79
|
-
eventId: eventIdFor(run.runId, sequence),
|
|
80
|
-
runId: run.runId,
|
|
81
|
-
sequence,
|
|
82
|
-
executableRef: run.executableRef,
|
|
83
|
-
rootRunId: run.rootRunId,
|
|
84
|
-
depth: run.depth,
|
|
85
|
-
occurredAt,
|
|
86
|
-
...(run.parentRunId === undefined ? {} : { parentRunId: run.parentRunId }),
|
|
87
|
-
...(run.message.causationId === undefined ? {} : { causationId: run.message.causationId }),
|
|
88
|
-
...(run.message.correlationId === undefined ? {} : { correlationId: run.message.correlationId }),
|
|
89
|
-
...(run.attempt > 0 ? { attemptId: `${run.runId}:attempt:${run.attempt}` } : {}),
|
|
90
|
-
...partial,
|
|
91
|
-
};
|
|
95
|
+
const event = makeEvent(run, partial, sequence, occurredAt);
|
|
92
96
|
yield* sql `
|
|
93
97
|
INSERT INTO tenetkit_run_events (run_id, sequence, event_id, event_json)
|
|
94
98
|
VALUES (${run.runId}, ${sequence}, ${event.eventId}, ${encodeEvent(event)})
|
|
@@ -99,23 +103,19 @@ export const appendEvent = Function.dual((args) => args.length >= 4 || (args.len
|
|
|
99
103
|
`)[0];
|
|
100
104
|
yield* sql `
|
|
101
105
|
INSERT INTO tenetkit_tree_event_index (root_run_id, position, run_id, run_sequence, event_id)
|
|
102
|
-
VALUES (${run.rootRunId}, ${
|
|
106
|
+
VALUES (${run.rootRunId}, ${treeRoot.last_position}, ${run.runId}, ${sequence}, ${event.eventId})
|
|
103
107
|
`;
|
|
104
108
|
const status = nextStatus ?? run.status;
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
const terminalEventId = event
|
|
111
|
-
? event.eventId
|
|
112
|
-
: (run.terminalEventId ?? null);
|
|
109
|
+
let activeWaitId = run.activeWaitId ?? null;
|
|
110
|
+
if (event._tag === "RunWaiting")
|
|
111
|
+
activeWaitId = event.wait.waitId;
|
|
112
|
+
if (event._tag === "RunResumed")
|
|
113
|
+
activeWaitId = null;
|
|
114
|
+
const terminalEventId = isTerminalEvent(event) ? event.eventId : (run.terminalEventId ?? null);
|
|
113
115
|
const cancellationRequested = event._tag === "RunCancellationRequested" || run.cancellationRequested;
|
|
114
|
-
const cancelReason = event._tag === "RunCancellationRequested"
|
|
115
|
-
? event.reason
|
|
116
|
-
: (run.cancelReason ?? null);
|
|
116
|
+
const cancelReason = event._tag === "RunCancellationRequested" ? (event.reason ?? null) : (run.cancelReason ?? null);
|
|
117
117
|
const attempt = event._tag === "RunAttemptStarted" ? event.attempt : run.attempt;
|
|
118
|
-
const terminalPartial = event
|
|
118
|
+
const terminalPartial = isTerminalEvent(event);
|
|
119
119
|
if (terminalPartial) {
|
|
120
120
|
yield* sql `
|
|
121
121
|
UPDATE tenetkit_runs SET
|
|
@@ -171,9 +171,7 @@ export const promoteHead = Function.dual(3, (hub, address, sessionId) => Effect.
|
|
|
171
171
|
WHERE address = ${address} AND session_id = ${sessionId}
|
|
172
172
|
`;
|
|
173
173
|
}
|
|
174
|
-
|
|
175
|
-
if (head === undefined || head.status !== "queued" || head.cancellationRequested)
|
|
176
|
-
return;
|
|
174
|
+
yield* loadRun(headId);
|
|
177
175
|
}));
|
|
178
176
|
export const removeFromLane = Function.dual(3, (address, sessionId, runId) => Effect.gen(function* () {
|
|
179
177
|
const sql = yield* SqlClient.SqlClient;
|
|
@@ -217,7 +215,7 @@ export const completeRun = Function.dual(3, (hub, run, result) => Effect.gen(fun
|
|
|
217
215
|
`;
|
|
218
216
|
return;
|
|
219
217
|
}
|
|
220
|
-
const event = yield* appendEvent(hub, run, { _tag: "RunCancelled", ...(run.cancelReason === undefined ?
|
|
218
|
+
const event = yield* appendEvent(hub, run, { _tag: "RunCancelled", ...(run.cancelReason === undefined ? undefined : { reason: run.cancelReason }) }, "cancelled");
|
|
221
219
|
const settled = (yield* loadRun(run.runId));
|
|
222
220
|
yield* settleParent(hub, settled, event.eventId);
|
|
223
221
|
yield* afterTerminal(hub, settled);
|
|
@@ -292,10 +290,13 @@ export const settleParent = Function.dual(3, (hub, child, terminalEventId) => Ef
|
|
|
292
290
|
yield* sql `UPDATE tenetkit_runs SET attempt_fence = ${attempt} WHERE run_id = ${parent.runId}`;
|
|
293
291
|
yield* appendEvent(hub, { ...currentParent, attempt }, { _tag: "RunAttemptStarted", attempt }, "running");
|
|
294
292
|
}
|
|
295
|
-
return;
|
|
296
293
|
}
|
|
297
|
-
if (currentParent?.status
|
|
298
|
-
|
|
294
|
+
else if (currentParent?.status === "cancelling" && currentParent.ownerWorkerId === undefined) {
|
|
295
|
+
yield* settleCancelledParent(hub, currentParent);
|
|
296
|
+
}
|
|
297
|
+
}));
|
|
298
|
+
const settleCancelledParent = (hub, parent) => Effect.gen(function* () {
|
|
299
|
+
const sql = yield* SqlClient.SqlClient;
|
|
299
300
|
const running = yield* sql `
|
|
300
301
|
SELECT fan_out_id FROM tenetkit_fan_outs WHERE parent_run_id = ${parent.runId} AND status = 'running' LIMIT 1
|
|
301
302
|
`;
|
|
@@ -305,14 +306,14 @@ export const settleParent = Function.dual(3, (hub, child, terminalEventId) => Ef
|
|
|
305
306
|
return;
|
|
306
307
|
if (yield* hasUnsettledChild(parent.runId))
|
|
307
308
|
return;
|
|
308
|
-
const cancelled = yield* appendEvent(hub,
|
|
309
|
+
const cancelled = yield* appendEvent(hub, parent, {
|
|
309
310
|
_tag: "RunCancelled",
|
|
310
|
-
...(
|
|
311
|
+
...(parent.cancelReason === undefined ? undefined : { reason: parent.cancelReason }),
|
|
311
312
|
}, "cancelled");
|
|
312
313
|
const settledParent = (yield* loadRun(parent.runId));
|
|
313
314
|
yield* settleParent(hub, settledParent, cancelled.eventId);
|
|
314
315
|
yield* afterTerminal(hub, settledParent);
|
|
315
|
-
})
|
|
316
|
+
});
|
|
316
317
|
export const insertRun = (input) => Effect.gen(function* () {
|
|
317
318
|
const sql = yield* SqlClient.SqlClient;
|
|
318
319
|
yield* sql `
|
|
@@ -3,7 +3,7 @@ import { SqlClient } from "effect/unstable/sql";
|
|
|
3
3
|
import { RunNotFound, RunTerminal, RuntimeUnavailable } from "tenetkit/runtime/driver/errors";
|
|
4
4
|
import { StaleClaim } from "tenetkit/runtime/driver/sql/errors";
|
|
5
5
|
import type { SqlError } from "effect/unstable/sql/SqlError";
|
|
6
|
-
import type { Interface as RunStoreInterface } from "tenetkit/runtime/driver/run
|
|
6
|
+
import type { Interface as RunStoreInterface } from "tenetkit/runtime/driver/run/store";
|
|
7
7
|
import type { EventHub } from "tenetkit/runtime/driver/sql/subscribers";
|
|
8
8
|
type SuspendEffect = Effect.Effect<undefined, RunNotFound | RunTerminal | RuntimeUnavailable | SqlError | StaleClaim, SqlClient.SqlClient>;
|
|
9
9
|
export declare const suspend: {
|
|
@@ -2,18 +2,18 @@ import { Effect, Function, Option } from "effect";
|
|
|
2
2
|
import { SqlClient } from "effect/unstable/sql";
|
|
3
3
|
import { RunNotFound, RunTerminal, RuntimeUnavailable } from "tenetkit/runtime/driver/errors";
|
|
4
4
|
import { StaleClaim } from "tenetkit/runtime/driver/sql/errors";
|
|
5
|
-
import { checkpointRef } from "tenetkit/runtime/driver/executable
|
|
5
|
+
import { checkpointRef } from "tenetkit/runtime/driver/executable/manifest";
|
|
6
6
|
import { isTerminal } from "tenetkit/runtime/driver/run";
|
|
7
|
-
import { encodeContinuation } from "tenetkit/runtime/driver/steering";
|
|
8
|
-
import { encodeExecutableRef, encodeJson } from "tenetkit/runtime/driver/sql/codecs";
|
|
9
|
-
import { encodeReason, WaitResolution } from "tenetkit/runtime/driver/run
|
|
10
|
-
import { lockRun } from "
|
|
11
|
-
import { appendEvent, requireRun } from "./
|
|
12
|
-
import { requireExecutionClaim } from "tenetkit/runtime/driver/sql/store
|
|
13
|
-
import { groupIdFromSuspension, resultFromInspection } from "tenetkit/runtime/driver/child
|
|
14
|
-
import { inspectFanOut } from "tenetkit/runtime/driver/sql/store
|
|
15
|
-
import { ExecutionCheckpoint, ExecutionSuspension } from "tenetkit/runtime/driver/execution
|
|
16
|
-
import { loadTerminalEvent, reconcileChildWaitWith } from "tenetkit/runtime/driver/sql/store
|
|
7
|
+
import { encodeContinuation } from "tenetkit/runtime/driver/run/steering";
|
|
8
|
+
import { encodeExecutableRef, encodeJson } from "tenetkit/runtime/driver/sql/codec/codecs";
|
|
9
|
+
import { encodeReason, WaitResolution } from "tenetkit/runtime/driver/run/wait";
|
|
10
|
+
import { lockRun } from "../runs/locks.js";
|
|
11
|
+
import { appendEvent, requireRun } from "./runtime.js";
|
|
12
|
+
import { requireExecutionClaim } from "tenetkit/runtime/driver/sql/store/execution";
|
|
13
|
+
import { groupIdFromSuspension, resultFromInspection } from "tenetkit/runtime/driver/child/group";
|
|
14
|
+
import { inspectFanOut } from "tenetkit/runtime/driver/sql/store/fan-out/service";
|
|
15
|
+
import { ExecutionCheckpoint, ExecutionSuspension } from "tenetkit/runtime/driver/execution/state";
|
|
16
|
+
import { loadTerminalEvent, reconcileChildWaitWith } from "tenetkit/runtime/driver/sql/store/child/settlement";
|
|
17
17
|
export const suspend = Function.dual(2, (hub, input) => Effect.gen(function* () {
|
|
18
18
|
const sql = yield* SqlClient.SqlClient;
|
|
19
19
|
yield* lockRun(input.runId);
|
|
@@ -49,9 +49,9 @@ export const suspend = Function.dual(2, (hub, input) => Effect.gen(function* ()
|
|
|
49
49
|
status = 'open', reason = EXCLUDED.reason, response_json = NULL, opened_at = EXCLUDED.opened_at, closed_at = NULL
|
|
50
50
|
`;
|
|
51
51
|
yield* appendEvent(hub, loaded, { _tag: "RunWaiting", wait: input.wait }, "waiting");
|
|
52
|
-
const child =
|
|
53
|
-
?
|
|
54
|
-
:
|
|
52
|
+
const child = input.suspension.token === undefined
|
|
53
|
+
? Option.none()
|
|
54
|
+
: yield* requireRun(input.suspension.token).pipe(Effect.option);
|
|
55
55
|
if (child._tag === "Some" && child.value.terminalEventId !== undefined) {
|
|
56
56
|
const terminalEvent = yield* loadTerminalEvent(child.value.terminalEventId);
|
|
57
57
|
if (terminalEvent !== undefined) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://json.schemastore.org/package.json",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.41.2",
|
|
4
4
|
"private": false,
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
41
|
"@effect/sql-pg": "4.0.0-rc.111",
|
|
42
|
-
"tenetkit": "0.
|
|
42
|
+
"tenetkit": "0.41.2"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
45
|
"@effect/vitest": "4.0.0-rc.111",
|
|
File without changes
|