@tenetkit/pg 0.37.0 → 0.38.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.
@@ -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" | "getOperation" | "getOperationByKey" | "resolveOperation">;
20
+ }) => Pick<RunStoreInterface, "recordOperation" | "startOperation" | "completeOperation" | "commitModelResponse" | "commitInterruptedModelResponse" | "expireRunningOperation" | "recoverRunningOperations" | "getOperation" | "getOperationByKey" | "resolveOperation">;
21
21
  export {};
@@ -18,6 +18,38 @@ import { lockRunHierarchy } from "./locks.js";
18
18
  export const postgresOperations = (input) => {
19
19
  const { sql, hub, run, runNoTxn, requireRun, requireClaim, nextId } = input;
20
20
  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)));
21
+ const expire = (op) => Effect.gen(function* () {
22
+ const loaded = yield* requireRun(op.runId);
23
+ const rows = yield* sql `
24
+ SELECT * FROM tenetkit_run_operations WHERE run_id = ${op.runId} AND operation_id = ${op.operationId}
25
+ `;
26
+ const row = rows[0];
27
+ if (row === undefined)
28
+ return yield* RuntimeUnavailable.make({ message: "operation missing" });
29
+ if (row.status !== "running") {
30
+ return { record: toOperationRecord(row), outcome: row.status };
31
+ }
32
+ if (canBlindRetry(row.replay_policy)) {
33
+ yield* sql `
34
+ UPDATE tenetkit_run_operations
35
+ SET status = 'requested', started_at = NULL, finished_at = NULL, owner_worker_id = NULL, lease_expires_at = NULL
36
+ WHERE run_id = ${op.runId} AND operation_id = ${op.operationId} AND status = 'running'
37
+ `;
38
+ const next = yield* sql `
39
+ SELECT * FROM tenetkit_run_operations WHERE run_id = ${op.runId} AND operation_id = ${op.operationId}
40
+ `;
41
+ return { record: toOperationRecord(next[0]), outcome: "retried" };
42
+ }
43
+ yield* sql `
44
+ UPDATE tenetkit_run_operations SET status = 'unknown', finished_at = NOW()
45
+ WHERE run_id = ${op.runId} AND operation_id = ${op.operationId} AND status = 'running'
46
+ `;
47
+ yield* appendEvent(hub, loaded, { _tag: "OperationUnknown", operationId: op.operationId }, loaded.cancellationRequested ? "cancelling" : "needs-resolution");
48
+ const next = yield* sql `
49
+ SELECT * FROM tenetkit_run_operations WHERE run_id = ${op.runId} AND operation_id = ${op.operationId}
50
+ `;
51
+ return { record: toOperationRecord(next[0]), outcome: "unknown" };
52
+ });
21
53
  return {
22
54
  recordOperation: (op) => fenced(op, Effect.gen(function* () {
23
55
  const loaded = yield* requireRun(op.runId);
@@ -212,37 +244,18 @@ export const postgresOperations = (input) => {
212
244
  return toOperationRecord(rows[0]);
213
245
  })),
214
246
  ...postgresModelResponseOperations(input),
215
- expireRunningOperation: (op) => fenced(op, Effect.gen(function* () {
216
- const loaded = yield* requireRun(op.runId);
217
- const rows = yield* sql `
218
- SELECT * FROM tenetkit_run_operations WHERE run_id = ${op.runId} AND operation_id = ${op.operationId}
247
+ expireRunningOperation: (op) => fenced(op, expire(op)),
248
+ recoverRunningOperations: (claim) => fenced(claim, Effect.gen(function* () {
249
+ const operations = yield* sql `
250
+ SELECT operation_id FROM tenetkit_run_operations
251
+ WHERE run_id = ${claim.runId} AND status = 'running'
252
+ ORDER BY operation_id
219
253
  `;
220
- const row = rows[0];
221
- if (row === undefined)
222
- return yield* RuntimeUnavailable.make({ message: "operation missing" });
223
- if (row.status !== "running") {
224
- return { record: toOperationRecord(row), outcome: row.status };
225
- }
226
- if (canBlindRetry(row.replay_policy)) {
227
- yield* sql `
228
- UPDATE tenetkit_run_operations
229
- SET status = 'requested', started_at = NULL, finished_at = NULL, owner_worker_id = NULL, lease_expires_at = NULL
230
- WHERE run_id = ${op.runId} AND operation_id = ${op.operationId} AND status = 'running'
231
- `;
232
- const next = yield* sql `
233
- SELECT * FROM tenetkit_run_operations WHERE run_id = ${op.runId} AND operation_id = ${op.operationId}
234
- `;
235
- return { record: toOperationRecord(next[0]), outcome: "retried" };
254
+ for (const operation of operations) {
255
+ yield* expire({ runId: claim.runId, operationId: operation.operation_id });
236
256
  }
237
- yield* sql `
238
- UPDATE tenetkit_run_operations SET status = 'unknown', finished_at = NOW()
239
- WHERE run_id = ${op.runId} AND operation_id = ${op.operationId} AND status = 'running'
240
- `;
241
- yield* appendEvent(hub, loaded, { _tag: "OperationUnknown", operationId: op.operationId }, loaded.cancellationRequested ? "cancelling" : "needs-resolution");
242
- const next = yield* sql `
243
- SELECT * FROM tenetkit_run_operations WHERE run_id = ${op.runId} AND operation_id = ${op.operationId}
244
- `;
245
- return { record: toOperationRecord(next[0]), outcome: "unknown" };
257
+ const loaded = yield* requireRun(claim.runId);
258
+ return loaded.status === "needs-resolution" ? "blocked" : "ready";
246
259
  })),
247
260
  getOperation: (op) => runNoTxn(Effect.gen(function* () {
248
261
  yield* requireRun(op.runId);
@@ -35,6 +35,7 @@ import { lockMailbox, lockRun, lockRunHierarchy, lockSpawnParent } from "./locks
35
35
  import { inspectionStoreMethods } from "./store-inspection.js";
36
36
  import { programStoreMethods } from "./store-program.js";
37
37
  import { admitStart as admitExactStart } from "tenetkit/runtime/driver/sql/store-admit";
38
+ import { activateRoot } from "tenetkit/runtime/driver/sql/store-activate";
38
39
  import { admitSend } from "./store-admit.js";
39
40
  import { associateRegistrations, loadRegistrations } from "tenetkit/runtime/driver/sql/executable-registrations";
40
41
  import { narrow } from "tenetkit/runtime/driver/executable-registration";
@@ -71,7 +72,8 @@ export const makePostgresServices = (options) => Effect.gen(function* () {
71
72
  sessionStore: (sessionId) => Effect.succeed(Option.some(makePostgresSessionStore({ sessionId, run, runNoTxn }))),
72
73
  hasAdmission: (input) => runNoTxn(hasAdmission(input)),
73
74
  admitSend: (input) => run(admitSend(transactionHub, addressBindings, nextId, input)),
74
- admitStart: (input) => run(sql `SELECT pg_advisory_xact_lock(hashtext('tenetkit:executable-registrations'))`.pipe(Effect.andThen(admitExactStart(transactionHub, input)))),
75
+ admitStart: (input, startOptions) => run(sql `SELECT pg_advisory_xact_lock(hashtext('tenetkit:executable-registrations'))`.pipe(Effect.andThen(admitExactStart(transactionHub, input, startOptions)))),
76
+ activate: (input) => run(lockRun(input.runId).pipe(Effect.andThen(activateRoot(transactionHub, input.runId)))),
75
77
  admitSpawn: (input) => run(Effect.gen(function* () {
76
78
  const parent = yield* lockSpawnParent(input.parentRunId);
77
79
  const executableRef = resolveChild(parent.executableRef, parent.executableManifest, input.selection);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/package.json",
3
- "version": "0.37.0",
3
+ "version": "0.38.1",
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.37.0"
42
+ "tenetkit": "0.38.1"
43
43
  },
44
44
  "devDependencies": {
45
45
  "@effect/vitest": "4.0.0-rc.111",