@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.
@@ -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: {
@@ -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
- r.parent_run_id IS NULL
14
+ (r.cancellation_requested = TRUE AND r.status = 'cancelling')
15
+ OR (
16
+ r.cancellation_requested = FALSE
17
17
  AND (
18
- r.status = 'running'
19
- OR EXISTS (SELECT 1 FROM tenetkit_lanes l WHERE l.head_run_id = r.run_id)
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 = FALSE
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 || (yield* hasUnsettledChild(run.runId))) {
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 === "succeeded" || row.status === "failed" || row.status === "unknown") {
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);
@@ -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.38.4",
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.38.4"
42
+ "tenetkit": "0.39.0"
43
43
  },
44
44
  "devDependencies": {
45
45
  "@effect/vitest": "4.0.0-rc.111",