@tenetkit/pg 0.38.4 → 0.39.0
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/claims.d.ts +1 -0
- package/dist/postgres/claims.js +15 -10
- package/dist/postgres/pg-helpers.js +6 -2
- package/dist/postgres/store-cancel.js +9 -1
- package/dist/postgres/store-claims.js +1 -0
- package/dist/postgres/store-ops.d.ts +1 -1
- package/dist/postgres/store-ops.js +15 -2
- package/dist/postgres/store.js +3 -1
- package/package.json +2 -2
|
@@ -12,6 +12,7 @@ export declare const refreshLease: (input: {
|
|
|
12
12
|
readonly runId: string;
|
|
13
13
|
readonly workerId: string;
|
|
14
14
|
readonly attemptFence: number;
|
|
15
|
+
readonly cancellationRequested: boolean;
|
|
15
16
|
readonly lease: Duration.Input;
|
|
16
17
|
}) => Effect.Effect<boolean, import("effect/unstable/sql/SqlError").SqlError, SqlClient.SqlClient>;
|
|
17
18
|
export declare const requireClaim: (input: {
|
package/dist/postgres/claims.js
CHANGED
|
@@ -10,19 +10,24 @@ export const claimReadyRuns = (options) => Effect.gen(function* () {
|
|
|
10
10
|
SELECT r.run_id
|
|
11
11
|
FROM tenetkit_runs r
|
|
12
12
|
WHERE r.status IN ('queued', 'running', 'cancelling')
|
|
13
|
-
AND r.cancellation_requested = FALSE
|
|
14
13
|
AND (
|
|
15
|
-
(
|
|
16
|
-
|
|
14
|
+
(r.cancellation_requested = TRUE AND r.status = 'cancelling')
|
|
15
|
+
OR (
|
|
16
|
+
r.cancellation_requested = FALSE
|
|
17
17
|
AND (
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
(
|
|
19
|
+
r.parent_run_id IS NULL
|
|
20
|
+
AND (
|
|
21
|
+
r.status = 'running'
|
|
22
|
+
OR EXISTS (SELECT 1 FROM tenetkit_lanes l WHERE l.head_run_id = r.run_id)
|
|
23
|
+
)
|
|
24
|
+
)
|
|
25
|
+
OR EXISTS (
|
|
26
|
+
SELECT 1 FROM tenetkit_run_links link
|
|
27
|
+
WHERE link.child_run_id = r.run_id AND link.readiness = 'ready'
|
|
28
|
+
)
|
|
20
29
|
)
|
|
21
30
|
)
|
|
22
|
-
OR EXISTS (
|
|
23
|
-
SELECT 1 FROM tenetkit_run_links link
|
|
24
|
-
WHERE link.child_run_id = r.run_id AND link.readiness = 'ready'
|
|
25
|
-
)
|
|
26
31
|
)
|
|
27
32
|
AND (
|
|
28
33
|
r.owner_worker_id IS NULL
|
|
@@ -74,7 +79,7 @@ export const refreshLease = (input) => Effect.gen(function* () {
|
|
|
74
79
|
WHERE run_id = ${input.runId}
|
|
75
80
|
AND owner_worker_id = ${input.workerId}
|
|
76
81
|
AND attempt_fence = ${input.attemptFence}
|
|
77
|
-
AND cancellation_requested =
|
|
82
|
+
AND cancellation_requested = ${input.cancellationRequested}
|
|
78
83
|
AND status NOT IN ('succeeded', 'failed', 'cancelled')
|
|
79
84
|
RETURNING run_id
|
|
80
85
|
`;
|
|
@@ -12,7 +12,7 @@ import { RunNotFound, RunTerminal, RuntimeUnavailable } from "tenetkit/runtime/d
|
|
|
12
12
|
import { StaleClaim } from "tenetkit/runtime/driver/sql/errors";
|
|
13
13
|
import { admitChildSettlementFromEventId } from "tenetkit/runtime/driver/sql/settlement-notifications";
|
|
14
14
|
import { discardPendingSteering } from "tenetkit/runtime/driver/sql/store-steering-disposition";
|
|
15
|
-
import { hasUnsettledChild, loadTerminalEvent, reconcileChildWaitWith, } from "tenetkit/runtime/driver/sql/store-child-settlement";
|
|
15
|
+
import { hasPendingOperationCancellation, hasUnsettledChild, loadTerminalEvent, reconcileChildWaitWith, } from "tenetkit/runtime/driver/sql/store-child-settlement";
|
|
16
16
|
import { appendTerminalToolResultsForEvent } from "tenetkit/runtime/driver/sql/session-terminalization";
|
|
17
17
|
export const loadRun = (runId) => Effect.gen(function* () {
|
|
18
18
|
const sql = yield* SqlClient.SqlClient;
|
|
@@ -209,7 +209,9 @@ export const completeRun = Function.dual(3, (hub, run, result) => Effect.gen(fun
|
|
|
209
209
|
const runningFanOut = yield* sql `
|
|
210
210
|
SELECT fan_out_id FROM tenetkit_fan_outs WHERE parent_run_id = ${run.runId} AND status = 'running' LIMIT 1
|
|
211
211
|
`;
|
|
212
|
-
if (runningFanOut.length > 0 ||
|
|
212
|
+
if (runningFanOut.length > 0 ||
|
|
213
|
+
(yield* hasPendingOperationCancellation(run.runId)) ||
|
|
214
|
+
(yield* hasUnsettledChild(run.runId))) {
|
|
213
215
|
yield* sql `
|
|
214
216
|
UPDATE tenetkit_runs SET owner_worker_id = NULL, lease_expires_at = NULL WHERE run_id = ${run.runId}
|
|
215
217
|
`;
|
|
@@ -299,6 +301,8 @@ export const settleParent = Function.dual(3, (hub, child, terminalEventId) => Ef
|
|
|
299
301
|
`;
|
|
300
302
|
if (running.length > 0)
|
|
301
303
|
return;
|
|
304
|
+
if (yield* hasPendingOperationCancellation(parent.runId))
|
|
305
|
+
return;
|
|
302
306
|
if (yield* hasUnsettledChild(parent.runId))
|
|
303
307
|
return;
|
|
304
308
|
const cancelled = yield* appendEvent(hub, currentParent, {
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { Effect, Function } from "effect";
|
|
2
2
|
import { RunNotFound, RuntimeUnavailable } from "tenetkit/runtime/driver/errors";
|
|
3
3
|
import { isTerminal } from "tenetkit/runtime/driver/run";
|
|
4
|
-
import { hasUnsettledChild } from "tenetkit/runtime/driver/sql/store-child-settlement";
|
|
4
|
+
import { hasPendingOperationCancellation, hasUnsettledChild } from "tenetkit/runtime/driver/sql/store-child-settlement";
|
|
5
|
+
import { markOperationCancellations } from "tenetkit/runtime/driver/sql/store-operations";
|
|
5
6
|
import { afterTerminal, appendEvent, loadRun, settleParent } from "./pg-helpers.js";
|
|
6
7
|
import { cancelOwnedFanOuts } from "./store-fan-out.js";
|
|
7
8
|
import { reconcileProgramCancellation } from "tenetkit/runtime/driver/sql/store-program";
|
|
@@ -24,6 +25,11 @@ export const makeCancelRun = (input) => {
|
|
|
24
25
|
yield* appendEvent(input.hub, current, { _tag: "RunCancellationRequested", ...(reason === undefined ? {} : { reason }) }, needsResolution ? "needs-resolution" : "cancelling");
|
|
25
26
|
current = (yield* loadRun(runId));
|
|
26
27
|
}
|
|
28
|
+
const marked = terminal ? 0 : yield* markOperationCancellations(runId);
|
|
29
|
+
if (marked > 0 && current.status === "needs-resolution") {
|
|
30
|
+
yield* input.sql `UPDATE tenetkit_runs SET status = 'cancelling' WHERE run_id = ${runId}`;
|
|
31
|
+
current = (yield* loadRun(runId));
|
|
32
|
+
}
|
|
27
33
|
if (!terminal)
|
|
28
34
|
yield* reconcileProgramCancellation(runId, reason ?? current.cancelReason);
|
|
29
35
|
yield* input.sql `
|
|
@@ -62,6 +68,8 @@ export const makeCancelRun = (input) => {
|
|
|
62
68
|
`;
|
|
63
69
|
if (running.length > 0)
|
|
64
70
|
return;
|
|
71
|
+
if (yield* hasPendingOperationCancellation(runId))
|
|
72
|
+
return;
|
|
65
73
|
if (yield* hasUnsettledChild(runId))
|
|
66
74
|
return;
|
|
67
75
|
const event = yield* appendEvent(input.hub, current, { _tag: "RunCancelled", ...(reason === undefined ? {} : { reason }) }, "cancelled");
|
|
@@ -30,6 +30,7 @@ export const makePostgresClaims = (input) => {
|
|
|
30
30
|
runId: leaseInput.runId,
|
|
31
31
|
workerId: leaseInput.workerId,
|
|
32
32
|
attemptFence: leaseInput.attemptFence,
|
|
33
|
+
cancellationRequested: leaseInput.cancellationRequested,
|
|
33
34
|
lease: leaseInput.lease ?? "30 seconds",
|
|
34
35
|
})),
|
|
35
36
|
releaseClaim: (releaseInput) => run(releaseClaim({
|
|
@@ -17,5 +17,5 @@ export declare const postgresOperations: (input: {
|
|
|
17
17
|
readonly requireRun: (runId: string) => Effect.Effect<DecodedRun, RunNotFound | RuntimeUnavailable | SqlError, SqlR>;
|
|
18
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
|
-
}) => Pick<RunStoreInterface, "recordOperation" | "startOperation" | "completeOperation" | "commitModelResponse" | "commitInterruptedModelResponse" | "expireRunningOperation" | "recoverRunningOperations" | "getOperation" | "getOperationByKey" | "resolveOperation">;
|
|
20
|
+
}) => Pick<RunStoreInterface, "recordOperation" | "startOperation" | "completeOperation" | "commitModelResponse" | "commitInterruptedModelResponse" | "expireRunningOperation" | "recoverRunningOperations" | "getOperation" | "getOperationByKey" | "operationCancellations" | "acknowledgeOperationCancellation" | "resolveOperation">;
|
|
21
21
|
export {};
|
|
@@ -11,6 +11,7 @@ import { encodeContinuation } from "tenetkit/runtime/driver/steering";
|
|
|
11
11
|
import { checkpointRef } from "tenetkit/runtime/driver/executable-manifest";
|
|
12
12
|
import { getProgramOperation, resolveProgramOperation } from "tenetkit/runtime/driver/sql/store-program";
|
|
13
13
|
import { settleAdmittedCancellation } from "tenetkit/runtime/driver/sql/store-control";
|
|
14
|
+
import { acknowledgeOperationCancellation, operationCancellations } from "tenetkit/runtime/driver/sql/store-operations";
|
|
14
15
|
import { postgresModelResponseOperations } from "./store-model-response.js";
|
|
15
16
|
import { appendHandoffSessionEntry, verifyHandoffSessionEntry } from "./session-store.js";
|
|
16
17
|
import { handoffSessionEntry, isHandoffCommit, sameHandoffCheckpoint, sameHandoffCommit, } from "tenetkit/runtime/driver/handoff-session";
|
|
@@ -74,6 +75,9 @@ export const postgresOperations = (input) => {
|
|
|
74
75
|
}
|
|
75
76
|
return toOperationRecord(prior);
|
|
76
77
|
}
|
|
78
|
+
if (loaded.cancellationRequested) {
|
|
79
|
+
return yield* RuntimeUnavailable.make({ message: `run ${loaded.runId} is cancelling` });
|
|
80
|
+
}
|
|
77
81
|
const steeringEntryIds = op.steeringEntryIds ?? [];
|
|
78
82
|
const pending = yield* sql `
|
|
79
83
|
SELECT entry_id FROM tenetkit_run_steering
|
|
@@ -134,7 +138,10 @@ export const postgresOperations = (input) => {
|
|
|
134
138
|
return toOperationRecord(rows[0]);
|
|
135
139
|
})),
|
|
136
140
|
startOperation: (op) => fenced(op, Effect.gen(function* () {
|
|
137
|
-
yield* requireRun(op.runId);
|
|
141
|
+
const loaded = yield* requireRun(op.runId);
|
|
142
|
+
if (loaded.cancellationRequested) {
|
|
143
|
+
return yield* RuntimeUnavailable.make({ message: `run ${loaded.runId} is cancelling` });
|
|
144
|
+
}
|
|
138
145
|
yield* sql `
|
|
139
146
|
UPDATE tenetkit_run_operations
|
|
140
147
|
SET status = 'running', started_at = NOW()
|
|
@@ -159,7 +166,11 @@ export const postgresOperations = (input) => {
|
|
|
159
166
|
if (row === undefined)
|
|
160
167
|
return yield* RuntimeUnavailable.make({ message: "operation missing" });
|
|
161
168
|
const current = toOperationRecord(row);
|
|
162
|
-
if (row.status === "
|
|
169
|
+
if (row.status === "cancelling" ||
|
|
170
|
+
row.status === "cancelled" ||
|
|
171
|
+
row.status === "succeeded" ||
|
|
172
|
+
row.status === "failed" ||
|
|
173
|
+
row.status === "unknown") {
|
|
163
174
|
if (current.kind === "handoff" && current.status === "succeeded" && isHandoffCommit(current.result)) {
|
|
164
175
|
if (op.outcome._tag !== "Succeeded" ||
|
|
165
176
|
!sameHandoffCommit(current.result, op.outcome.value) ||
|
|
@@ -274,6 +285,8 @@ export const postgresOperations = (input) => {
|
|
|
274
285
|
`;
|
|
275
286
|
return rows[0] === undefined ? undefined : toOperationRecord(rows[0]);
|
|
276
287
|
})),
|
|
288
|
+
operationCancellations: (claim) => fenced(claim, operationCancellations(claim)),
|
|
289
|
+
acknowledgeOperationCancellation: (op) => fenced(op, acknowledgeOperationCancellation(op)),
|
|
277
290
|
resolveOperation: (op) => run(Effect.gen(function* () {
|
|
278
291
|
yield* lockRunHierarchy(op.runId);
|
|
279
292
|
const loaded = yield* requireRun(op.runId);
|
package/dist/postgres/store.js
CHANGED
|
@@ -45,6 +45,7 @@ import { reconcileCancellationRequested } from "tenetkit/runtime/driver/sql/sess
|
|
|
45
45
|
import { cancelSessionRuns } from "./session-cancellation.js";
|
|
46
46
|
import { makePostgresSessionStore } from "./session-store.js";
|
|
47
47
|
import { readinessForAdmission } from "tenetkit/runtime/driver/sql/store-child-capacity";
|
|
48
|
+
import { hasPendingOperationCancellation } from "tenetkit/runtime/driver/sql/store-child-settlement";
|
|
48
49
|
export const makePostgresServices = (options) => Effect.gen(function* () {
|
|
49
50
|
const source = options.source ?? "postgres";
|
|
50
51
|
const addressBindings = new Map(options.addresses.map((entry) => [entry.address, entry.executable]));
|
|
@@ -291,7 +292,8 @@ export const makePostgresServices = (options) => Effect.gen(function* () {
|
|
|
291
292
|
return yield* RunTerminal.make({ runId: loaded.runId, status: loaded.status });
|
|
292
293
|
}
|
|
293
294
|
if (loaded.cancellationRequested) {
|
|
294
|
-
if (yield* deferCancelledFanOutParent(sql, loaded.runId))
|
|
295
|
+
if ((yield* deferCancelledFanOutParent(sql, loaded.runId)) ||
|
|
296
|
+
(yield* hasPendingOperationCancellation(loaded.runId)))
|
|
295
297
|
return;
|
|
296
298
|
const event = yield* appendEvent(transactionHub, loaded, { _tag: "RunCancelled", ...(loaded.cancelReason === undefined ? {} : { reason: loaded.cancelReason }) }, "cancelled");
|
|
297
299
|
const settled = (yield* loadRun(loaded.runId));
|
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.39.0",
|
|
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.39.0"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
45
|
"@effect/vitest": "4.0.0-rc.111",
|