@yielded/agent-storage-cloudflare 0.1.0-beta.173 → 0.1.0-beta.175
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/DoMemoryStore.mjs +1 -1
- package/dist/DoMessageDeliveryStore.mjs +1 -1
- package/dist/DoStorageFailpoint.d.mts +3 -1
- package/dist/DoStorageFailpoint.mjs +7 -2
- package/dist/DoStorageFailpoint.mjs.map +1 -1
- package/dist/DoStorageFailpointTesting.mjs +1 -4
- package/dist/DoStorageFailpointTesting.mjs.map +1 -1
- package/dist/{DoStorageVersion-NKnQU3eR.d.mts → DoStorageVersion-Mc7CXMdN.d.mts} +2 -2
- package/dist/DoStorageVersion.d.mts +1 -1
- package/dist/DoStorageVersion.mjs +2 -2
- package/dist/DoSubmissionLedger.mjs +121 -67
- package/dist/DoSubmissionLedger.mjs.map +1 -1
- package/dist/DoSubscriptionStore.mjs.map +1 -1
- package/dist/{DoThreadStore-CtyahRTW.mjs → DoThreadStore-CgIZQUNR.mjs} +30 -25
- package/dist/DoThreadStore-CgIZQUNR.mjs.map +1 -0
- package/dist/DoThreadStore.mjs +1 -1
- package/dist/PortProtocol.d.mts +12 -0
- package/dist/PortRouting.mjs +6 -1
- package/dist/PortRouting.mjs.map +1 -1
- package/dist/{do-journal-_MdLGTd3.mjs → do-journal-7P3DUBz0.mjs} +140 -65
- package/dist/do-journal-7P3DUBz0.mjs.map +1 -0
- package/dist/index.d.mts +1 -1
- package/dist/index.mjs +1 -1
- package/dist/{migrations-C3N9GN6A.mjs → migrations-CAO_akhD.mjs} +45 -22
- package/dist/migrations-CAO_akhD.mjs.map +1 -0
- package/dist/{owned-state-BHzUi0eb.mjs → owned-state-B4QhezMp.mjs} +8 -6
- package/dist/owned-state-B4QhezMp.mjs.map +1 -0
- package/package.json +1 -1
- package/src/DoStorageFailpoint.ts +4 -0
- package/src/DoStorageFailpointTesting.ts +9 -7
- package/src/DoSubmissionLedger.ts +271 -150
- package/src/DoSubscriptionStore.ts +1 -0
- package/src/DoThreadStore.ts +27 -50
- package/src/PortRouting.ts +10 -2
- package/src/internal/canonical-append.ts +1 -1
- package/src/internal/do-journal.ts +987 -800
- package/src/internal/migrations.ts +53 -10
- package/src/internal/owned-state.ts +18 -7
- package/src/internal/prompt-checkpoint.ts +19 -13
- package/src/internal/storage-span.ts +22 -13
- package/dist/DoThreadStore-CtyahRTW.mjs.map +0 -1
- package/dist/do-journal-_MdLGTd3.mjs.map +0 -1
- package/dist/migrations-C3N9GN6A.mjs.map +0 -1
- package/dist/owned-state-BHzUi0eb.mjs.map +0 -1
package/dist/DoMemoryStore.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.mjs";
|
|
2
|
-
import { r as ownedState } from "./owned-state-
|
|
2
|
+
import { r as ownedState } from "./owned-state-B4QhezMp.mjs";
|
|
3
3
|
import { SqlMemoryLimits, SqlStorageOwner, memoryStoreLayerWithFailpoints } from "@yielded/agent/sql-memory-store";
|
|
4
4
|
import { Effect, Layer, Schema } from "effect";
|
|
5
5
|
import * as SqlClientService from "effect/sql/SqlClient";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.mjs";
|
|
2
2
|
import { DoStorageConfig } from "./DoStorageConfig.mjs";
|
|
3
3
|
import { DoStorageFailpoint } from "./DoStorageFailpoint.mjs";
|
|
4
|
-
import { i as initializeDoJournal } from "./do-journal-
|
|
4
|
+
import { i as initializeDoJournal } from "./do-journal-7P3DUBz0.mjs";
|
|
5
5
|
import { BrowserCrypto } from "@effect/platform-browser";
|
|
6
6
|
import { SqlLifecycleSource } from "@yielded/agent-storage-sql/sql-lifecycle-publication";
|
|
7
7
|
import { makeSqlMessageDeliveryStore } from "@yielded/agent-storage-sql/sql-message-delivery-store";
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { c as DoStorageFailpointError, l as DoStorageFailpointLocation } from "./DoStorageError-CxjMnzUA.mjs";
|
|
2
2
|
import { Context, Effect, Layer } from "effect";
|
|
3
3
|
declare namespace DoStorageFailpoint_d_exports {
|
|
4
|
-
export { DoStorageFailpoint, DoStorageFailpointHandler };
|
|
4
|
+
export { DoStorageFailpoint, DoStorageFailpointHandler, isDefaultDoStorageFailpoint };
|
|
5
5
|
}
|
|
6
6
|
export type DoStorageFailpointHandler = (location: DoStorageFailpointLocation) => Effect.Effect<void, DoStorageFailpointError>;
|
|
7
|
+
/** @internal Select a plain native body only for the library's no-op handler. */
|
|
8
|
+
export declare const isDefaultDoStorageFailpoint: (handler: DoStorageFailpointHandler) => boolean;
|
|
7
9
|
declare const DoStorageFailpoint_base: Context.ServiceClass<DoStorageFailpoint, "@effect-agent/storage-cloudflare/DoStorageFailpoint", {
|
|
8
10
|
readonly hit: DoStorageFailpointHandler;
|
|
9
11
|
}>;
|
|
@@ -1,14 +1,19 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.mjs";
|
|
2
2
|
import { Context, Effect, Layer } from "effect";
|
|
3
3
|
//#region src/DoStorageFailpoint.ts
|
|
4
|
-
var DoStorageFailpoint_exports = /* @__PURE__ */ __exportAll({
|
|
4
|
+
var DoStorageFailpoint_exports = /* @__PURE__ */ __exportAll({
|
|
5
|
+
DoStorageFailpoint: () => DoStorageFailpoint,
|
|
6
|
+
isDefaultDoStorageFailpoint: () => isDefaultDoStorageFailpoint
|
|
7
|
+
});
|
|
5
8
|
const noFailpoint = () => Effect.void;
|
|
9
|
+
/** @internal Select a plain native body only for the library's no-op handler. */
|
|
10
|
+
const isDefaultDoStorageFailpoint = (handler) => handler === noFailpoint;
|
|
6
11
|
/** Explicit fault-injection authority used at Durable Object storage operation boundaries. */
|
|
7
12
|
var DoStorageFailpoint = class extends Context.Service()("@effect-agent/storage-cloudflare/DoStorageFailpoint") {
|
|
8
13
|
/** Production default: no fault injection. */
|
|
9
14
|
static layer = Layer.succeed(this)({ hit: noFailpoint });
|
|
10
15
|
};
|
|
11
16
|
//#endregion
|
|
12
|
-
export { DoStorageFailpoint, DoStorageFailpoint_exports as t };
|
|
17
|
+
export { DoStorageFailpoint, isDefaultDoStorageFailpoint, DoStorageFailpoint_exports as t };
|
|
13
18
|
|
|
14
19
|
//# sourceMappingURL=DoStorageFailpoint.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DoStorageFailpoint.mjs","names":[],"sources":["../src/DoStorageFailpoint.ts"],"sourcesContent":["import { Context, Effect, Layer } from \"effect\";\n\nimport type { DoStorageFailpointError, DoStorageFailpointLocation } from \"./DoStorageError.ts\";\n\nexport type DoStorageFailpointHandler = (\n location: DoStorageFailpointLocation,\n) => Effect.Effect<void, DoStorageFailpointError>;\n\nconst noFailpoint: DoStorageFailpointHandler = () => Effect.void;\n\n/** Explicit fault-injection authority used at Durable Object storage operation boundaries. */\nexport class DoStorageFailpoint extends Context.Service<\n DoStorageFailpoint,\n {\n readonly hit: DoStorageFailpointHandler;\n }\n>()(\"@effect-agent/storage-cloudflare/DoStorageFailpoint\") {\n /** Production default: no fault injection. */\n static readonly layer = Layer.succeed(this)({ hit: noFailpoint });\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"DoStorageFailpoint.mjs","names":[],"sources":["../src/DoStorageFailpoint.ts"],"sourcesContent":["import { Context, Effect, Layer } from \"effect\";\n\nimport type { DoStorageFailpointError, DoStorageFailpointLocation } from \"./DoStorageError.ts\";\n\nexport type DoStorageFailpointHandler = (\n location: DoStorageFailpointLocation,\n) => Effect.Effect<void, DoStorageFailpointError>;\n\nconst noFailpoint: DoStorageFailpointHandler = () => Effect.void;\n\n/** @internal Select a plain native body only for the library's no-op handler. */\nexport const isDefaultDoStorageFailpoint = (handler: DoStorageFailpointHandler): boolean =>\n handler === noFailpoint;\n\n/** Explicit fault-injection authority used at Durable Object storage operation boundaries. */\nexport class DoStorageFailpoint extends Context.Service<\n DoStorageFailpoint,\n {\n readonly hit: DoStorageFailpointHandler;\n }\n>()(\"@effect-agent/storage-cloudflare/DoStorageFailpoint\") {\n /** Production default: no fault injection. */\n static readonly layer = Layer.succeed(this)({ hit: noFailpoint });\n}\n"],"mappings":";;;;;;;AAQA,MAAM,oBAA+C,OAAO;;AAG5D,MAAa,+BAA+B,YAC1C,YAAY;;AAGd,IAAa,qBAAb,cAAwC,QAAQ,QAK9C,CAAC,CAAC,qDAAqD,CAAC,CAAC;;CAEzD,OAAgB,QAAQ,MAAM,QAAQ,IAAI,CAAC,CAAC,EAAE,KAAK,YAAY,CAAC;AAClE"}
|
|
@@ -12,10 +12,7 @@ import { Effect } from "effect";
|
|
|
12
12
|
* The handles stay injected: this package never imports `cloudflare:workers`, so the harness
|
|
13
13
|
* that owns a `DurableObjectState` supplies the thunk.
|
|
14
14
|
*/
|
|
15
|
-
const evictionFailpointHandler = (options) => (location) => options.isArmed(location).pipe(Effect.flatMap((armed) => armed ? Effect.sync(() => {
|
|
16
|
-
options.evict(location);
|
|
17
|
-
throw new Error(`Durable Object eviction did not interrupt execution at ${location}.`);
|
|
18
|
-
}) : Effect.void));
|
|
15
|
+
const evictionFailpointHandler = (options) => (location) => options.isArmed(location).pipe(Effect.flatMap((armed) => armed ? Effect.sync(() => options.evict(location)).pipe(Effect.andThen(Effect.die(/* @__PURE__ */ new Error(`Durable Object eviction did not interrupt execution at ${location}.`)))) : Effect.void));
|
|
19
16
|
//#endregion
|
|
20
17
|
export { evictionFailpointHandler };
|
|
21
18
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DoStorageFailpointTesting.mjs","names":[],"sources":["../src/DoStorageFailpointTesting.ts"],"sourcesContent":["import { Effect } from \"effect\";\n\nimport type { DoStorageFailpointLocation } from \"./DoStorageError.ts\";\nimport type { DoStorageFailpointHandler } from \"./DoStorageFailpoint.ts\";\n\n/**\n * The DC-specific eviction failpoint mode: instead of failing typed, an armed hit evicts the\n * Durable Object through an injected `evict` thunk — in production-shaped harnesses that thunk\n * is `() => ctx.abort()`, the platform's real failure mode. `ctx.abort()` never returns (it\n * throws while destroying the in-memory instance and every in-flight implicit or explicit\n * storage transaction rolls back), so an armed hit ends the current Attempt exactly like an\n * unannounced platform eviction; DO storage — the only correctness-critical state — survives\n * for the next incarnation, which the persisted alarm wakes without any incoming request.\n *\n * The handles stay injected: this package never imports `cloudflare:workers`, so the harness\n * that owns a `DurableObjectState` supplies the thunk.\n */\nexport const evictionFailpointHandler =\n (options: {\n readonly isArmed: (location: DoStorageFailpointLocation) => Effect.Effect<boolean>;\n /** Kills the incarnation — e.g. `() => ctx.abort()`. Typed `void` because the platform\n * declares `abort` as returning, but it throws while destroying the instance. */\n readonly evict: (location: DoStorageFailpointLocation) => void;\n }): DoStorageFailpointHandler =>\n (location) =>\n options.isArmed(location).pipe(\n Effect.flatMap((armed) =>\n armed\n ? // `ctx.abort()` throws while destroying the instance; that throw surfaces as a\n // defect in the (already dying) incarnation. The defensive
|
|
1
|
+
{"version":3,"file":"DoStorageFailpointTesting.mjs","names":[],"sources":["../src/DoStorageFailpointTesting.ts"],"sourcesContent":["import { Effect } from \"effect\";\n\nimport type { DoStorageFailpointLocation } from \"./DoStorageError.ts\";\nimport type { DoStorageFailpointHandler } from \"./DoStorageFailpoint.ts\";\n\n/**\n * The DC-specific eviction failpoint mode: instead of failing typed, an armed hit evicts the\n * Durable Object through an injected `evict` thunk — in production-shaped harnesses that thunk\n * is `() => ctx.abort()`, the platform's real failure mode. `ctx.abort()` never returns (it\n * throws while destroying the in-memory instance and every in-flight implicit or explicit\n * storage transaction rolls back), so an armed hit ends the current Attempt exactly like an\n * unannounced platform eviction; DO storage — the only correctness-critical state — survives\n * for the next incarnation, which the persisted alarm wakes without any incoming request.\n *\n * The handles stay injected: this package never imports `cloudflare:workers`, so the harness\n * that owns a `DurableObjectState` supplies the thunk.\n */\nexport const evictionFailpointHandler =\n (options: {\n readonly isArmed: (location: DoStorageFailpointLocation) => Effect.Effect<boolean>;\n /** Kills the incarnation — e.g. `() => ctx.abort()`. Typed `void` because the platform\n * declares `abort` as returning, but it throws while destroying the instance. */\n readonly evict: (location: DoStorageFailpointLocation) => void;\n }): DoStorageFailpointHandler =>\n (location) =>\n options.isArmed(location).pipe(\n Effect.flatMap((armed) =>\n armed\n ? // `ctx.abort()` throws while destroying the instance; that throw surfaces as a\n // defect in the (already dying) incarnation. The defensive defect below keeps the\n // guarantee — nothing after an armed hit may observe in-memory state — even if a\n // harness supplies an evict thunk that returns.\n Effect.sync(() => options.evict(location)).pipe(\n Effect.andThen(\n Effect.die(\n // oxlint-disable-next-line effect/no-native-error -- A returning native eviction callback violates the host contract and must remain a defect.\n new Error(`Durable Object eviction did not interrupt execution at ${location}.`),\n ),\n ),\n )\n : Effect.void,\n ),\n );\n"],"mappings":";;;;;;;;;;;;;;AAiBA,MAAa,4BACV,aAMA,aACC,QAAQ,QAAQ,QAAQ,CAAC,CAAC,KACxB,OAAO,SAAS,UACd,QAKI,OAAO,WAAW,QAAQ,MAAM,QAAQ,CAAC,CAAC,CAAC,KACzC,OAAO,QACL,OAAO,oBAEL,IAAI,MAAM,0DAA0D,SAAS,EAAE,CACjF,CACF,CACF,IACA,OAAO,IACb,CACF"}
|
|
@@ -2,10 +2,10 @@ import "./DoStorageError-CxjMnzUA.mjs";
|
|
|
2
2
|
import { Effect } from "effect";
|
|
3
3
|
import "effect/sql/SqlClient";
|
|
4
4
|
//#region src/internal/migrations.d.ts
|
|
5
|
-
declare const CurrentDoStorageVersion =
|
|
5
|
+
declare const CurrentDoStorageVersion = 28;
|
|
6
6
|
declare namespace DoStorageVersion_d_exports {
|
|
7
7
|
export { CurrentDoStorageVersion };
|
|
8
8
|
}
|
|
9
9
|
//#endregion
|
|
10
10
|
export { CurrentDoStorageVersion as n, DoStorageVersion_d_exports as t };
|
|
11
|
-
//# sourceMappingURL=DoStorageVersion-
|
|
11
|
+
//# sourceMappingURL=DoStorageVersion-Mc7CXMdN.d.mts.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as CurrentDoStorageVersion } from "./DoStorageVersion-
|
|
1
|
+
import { n as CurrentDoStorageVersion } from "./DoStorageVersion-Mc7CXMdN.mjs";
|
|
2
2
|
export { CurrentDoStorageVersion };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.mjs";
|
|
2
|
-
import { t as CurrentDoStorageVersion } from "./migrations-
|
|
2
|
+
import { t as CurrentDoStorageVersion } from "./migrations-CAO_akhD.mjs";
|
|
3
3
|
//#region src/DoStorageVersion.ts
|
|
4
|
-
var DoStorageVersion_exports = /* @__PURE__ */ __exportAll({ CurrentDoStorageVersion: () =>
|
|
4
|
+
var DoStorageVersion_exports = /* @__PURE__ */ __exportAll({ CurrentDoStorageVersion: () => 28 });
|
|
5
5
|
//#endregion
|
|
6
6
|
export { CurrentDoStorageVersion, DoStorageVersion_exports as t };
|
|
7
7
|
|
|
@@ -2,18 +2,18 @@ import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.mjs";
|
|
|
2
2
|
import { DoStorageConfig } from "./DoStorageConfig.mjs";
|
|
3
3
|
import { DoStorageFailpoint } from "./DoStorageFailpoint.mjs";
|
|
4
4
|
import { DoLedgerError, DoStorageCorruptionError, DoStorageError } from "./DoStorageError.mjs";
|
|
5
|
-
import { n as ownedRows } from "./owned-state-
|
|
6
|
-
import { i as initializeDoJournal, r as decodeRows } from "./do-journal-
|
|
7
|
-
import { l as prepareCanonicalAppend, o as storageConfigLayer, s as storageFailpointLayer } from "./DoThreadStore-
|
|
5
|
+
import { n as ownedRows } from "./owned-state-B4QhezMp.mjs";
|
|
6
|
+
import { i as initializeDoJournal, r as decodeRows } from "./do-journal-7P3DUBz0.mjs";
|
|
7
|
+
import { l as prepareCanonicalAppend, o as storageConfigLayer, s as storageFailpointLayer } from "./DoThreadStore-CgIZQUNR.mjs";
|
|
8
8
|
import { BrowserCrypto } from "@effect/platform-browser";
|
|
9
9
|
import { Cause, Clock, Context, Crypto, DateTime, Effect, Layer, Option, Schema, Stream } from "effect";
|
|
10
10
|
import * as SqlClientService from "effect/sql/SqlClient";
|
|
11
|
+
import { SqliteClient } from "@effect/sql-sqlite-do";
|
|
11
12
|
import { definitionJson, makeCanonicalStorage, recordBatchId, runKey } from "@yielded/agent-storage-sql/sql-canonical-storage";
|
|
12
13
|
import { SqlStorageProgress } from "@yielded/agent-storage-sql/sql-storage-progress";
|
|
13
14
|
import { canonicalRecordJson } from "@yielded/agent-storage-sql/sql-thread-archive-range";
|
|
14
|
-
import { ApprovalDecision, CanonicalSequence, DefinitionDigests, Digest, PersistedJson, RecordEnvelope, SettlementOutcome, WorkerAdmission } from "@yielded/agent/records";
|
|
15
|
+
import { ApprovalDecision, CanonicalSequence, DefinitionDigests, Digest, PersistedJson, RecordEnvelope, RecordId, SettlementOutcome, WorkerAdmission } from "@yielded/agent/records";
|
|
15
16
|
import { AppendConflict, ThreadNotMaterialized, ThreadStoreDiagnostic, ThreadStoreError, makeTransferFactCheck } from "@yielded/agent/thread-store";
|
|
16
|
-
import { SqliteClient } from "@effect/sql-sqlite-do";
|
|
17
17
|
import { StorageOwner } from "@yielded/agent/run-storage";
|
|
18
18
|
import { decodeAbortFact, decodeAdmissionFact, decodeApprovalFact, decodeResolutionFact } from "@yielded/agent-storage-sql/sql-admission-facts";
|
|
19
19
|
import { InputMessage } from "@yielded/agent/messaging";
|
|
@@ -55,7 +55,7 @@ var SubmissionRow = class extends Schema.Class("SubmissionRow")({
|
|
|
55
55
|
receipt_id: BoundedIdentifier,
|
|
56
56
|
state: SubmissionState,
|
|
57
57
|
settled_outcome: Schema.NullOr(SettlementOutcome),
|
|
58
|
-
settled_record_id: Schema.NullOr(BoundedIdentifier),
|
|
58
|
+
settled_record_id: Schema.NullOr(BoundedIdentifier.pipe(Schema.decodeTo(RecordId))),
|
|
59
59
|
finalized_at: Schema.NullOr(BoundedTimestamp),
|
|
60
60
|
created_at: BoundedTimestamp,
|
|
61
61
|
ready_at: Schema.NullOr(BoundedTimestamp),
|
|
@@ -191,7 +191,7 @@ const decodeClaim = Schema.decodeUnknownEffect(Claim);
|
|
|
191
191
|
const decodeSettlement = Schema.decodeUnknownEffect(Settlement);
|
|
192
192
|
const decodeAbortIntent = Schema.decodeUnknownEffect(AbortIntent);
|
|
193
193
|
const decodeInputAppliedMarker = Schema.decodeUnknownEffect(InputAppliedMarker);
|
|
194
|
-
const decodeSubmissionSnapshotType = (input) =>
|
|
194
|
+
const decodeSubmissionSnapshotType = (input) => SubmissionSnapshot.makeEffect(input).pipe(Effect.mapError((issue) => new Schema.SchemaError(issue)));
|
|
195
195
|
const decodeSubmissionId = Schema.decodeUnknownEffect(SubmissionSnapshot.fields.submissionId);
|
|
196
196
|
const decodeQueueSequence = Schema.decodeUnknownEffect(QueueSequence);
|
|
197
197
|
const decodeUtcInstant = Schema.decodeUnknownEffect(Schema.DateTimeUtcFromString);
|
|
@@ -205,6 +205,26 @@ const decodeChildReservationSnapshotUnknown = Schema.decodeUnknownEffect(ChildBu
|
|
|
205
205
|
const decodeChildAttachmentSnapshot = Schema.decodeUnknownEffect(ChildAttachmentSnapshot);
|
|
206
206
|
const equivalentPersistedJson = Schema.toEquivalence(PersistedJson);
|
|
207
207
|
const equivalentUnknownResolution = Schema.toEquivalence(UnknownResolution);
|
|
208
|
+
const decodeAdmissionRequestType = Schema.decodeEffect(Schema.toType(AdmissionRequest));
|
|
209
|
+
const decodeSubmissionLookupType = Schema.decodeEffect(Schema.toType(SubmissionLookup));
|
|
210
|
+
const decodeClaimRequestType = Schema.decodeEffect(Schema.toType(ClaimRequest));
|
|
211
|
+
const decodeMarkInputAppliedRequestType = Schema.decodeEffect(Schema.toType(MarkInputAppliedRequest));
|
|
212
|
+
const decodeSettlementFinalizationType = Schema.decodeEffect(Schema.toType(SettlementFinalization));
|
|
213
|
+
const decodeClaimJoiningRequestType = Schema.decodeEffect(Schema.toType(ClaimJoiningRequest));
|
|
214
|
+
const decodeAbortIntentRequestType = Schema.decodeEffect(Schema.toType(AbortIntentRequest));
|
|
215
|
+
const decodeRecoverySnapshotRequestType = Schema.decodeEffect(Schema.toType(RecoverySnapshotRequest));
|
|
216
|
+
const SubmissionRows = Schema.Array(SubmissionRow);
|
|
217
|
+
const ChildReservationRows = Schema.Array(ChildReservationRow);
|
|
218
|
+
const MaxQueueSequenceRows = Schema.Array(MaxQueueSequenceRow);
|
|
219
|
+
const SubmissionWorkItems = Schema.Array(SubmissionWorkItem);
|
|
220
|
+
const decodeSubmissionWorkItems = Schema.decodeEffect(SubmissionWorkItems);
|
|
221
|
+
const equivalentWorkerOrigin = Schema.toEquivalence(Schema.optional(WorkerAdmission.fields.origin));
|
|
222
|
+
const decodeFirstWorkerAdmissions = Schema.decodeUnknownEffect(Schema.Array(Schema.Struct({ worker_admission_json: Schema.NullOr(BoundedStoredText) })));
|
|
223
|
+
const CanonicalSettlementRows = Schema.Array(Schema.Struct({
|
|
224
|
+
batch_id: Schema.fromJsonString(BoundedIdentifier),
|
|
225
|
+
record_id: Schema.fromJsonString(BoundedIdentifier),
|
|
226
|
+
record_json: BoundedStoredText
|
|
227
|
+
}));
|
|
208
228
|
const isDoStorageError = Schema.is(DoStorageError);
|
|
209
229
|
/** Wrap an adapter-internal failure into the port's LedgerError without erasing its tag. */
|
|
210
230
|
const internalFailure = (operation) => (error) => LedgerError.make({
|
|
@@ -319,7 +339,7 @@ const makeServices = Effect.fnUntraced(function* () {
|
|
|
319
339
|
millis,
|
|
320
340
|
iso: new Date(millis).toISOString()
|
|
321
341
|
}));
|
|
322
|
-
const decodeSubmissionRows = (operation, rowKey, rows) => decodeRows(
|
|
342
|
+
const decodeSubmissionRows = (operation, rowKey, rows) => decodeRows(SubmissionRows, "effect_agent_submissions", rowKey, rows).pipe(Effect.mapError(internalFailure(operation)));
|
|
323
343
|
const readSubmission = Effect.fnUntraced(function* (operation, submissionId) {
|
|
324
344
|
const found = yield* cached(rows.submissions.by("submission_id", submissionId), operation);
|
|
325
345
|
return Option.fromUndefinedOr(found[0]);
|
|
@@ -354,11 +374,14 @@ const makeServices = Effect.fnUntraced(function* () {
|
|
|
354
374
|
}));
|
|
355
375
|
if (row.parent_submission_id === null !== (row.parent_tool_call_id === null)) return yield* corruptionFailure(operation, "effect_agent_submissions", row.submission_id, "A parent linkage must record both the parent Submission and the parent Tool Call.");
|
|
356
376
|
const admission = yield* decodeAdmissionFact(row).pipe(Effect.mapError(decodeFailure));
|
|
377
|
+
const settledAt = row.finalized_at === null ? void 0 : yield* decodeUtcInstant(row.finalized_at).pipe(Effect.mapError(decodeFailure));
|
|
357
378
|
const readyAt = row.ready_at === null ? void 0 : yield* decodeUtcInstant(row.ready_at).pipe(Effect.mapError(decodeFailure));
|
|
358
379
|
const snapshot = yield* decodeSubmissionSnapshotType({
|
|
359
380
|
...admission,
|
|
360
381
|
state: row.state,
|
|
361
382
|
...row.settled_outcome === null ? {} : { settledOutcome: row.settled_outcome },
|
|
383
|
+
...settledAt === void 0 ? {} : { settledAt },
|
|
384
|
+
...row.settled_record_id === null ? {} : { settledRecordId: row.settled_record_id },
|
|
362
385
|
...readyAt === void 0 ? {} : { readyAt }
|
|
363
386
|
}).pipe(Effect.mapError(decodeFailure));
|
|
364
387
|
submissions.set(row, snapshot);
|
|
@@ -370,11 +393,7 @@ const makeServices = Effect.fnUntraced(function* () {
|
|
|
370
393
|
const found = yield* sql`SELECT ${recordBatchId(sql)} AS batch_id, record_id, ${canonicalRecordJson(sql)} AS record_json
|
|
371
394
|
FROM effect_agent_canonical_records WHERE thread_id = ${submission.thread_id}
|
|
372
395
|
AND record_id = ${JSON.stringify(recordId)}`.pipe(Effect.mapError(sqlFailure(operation)));
|
|
373
|
-
const decoded = yield* decodeRows(
|
|
374
|
-
batch_id: Schema.fromJsonString(BoundedIdentifier),
|
|
375
|
-
record_id: Schema.fromJsonString(BoundedIdentifier),
|
|
376
|
-
record_json: BoundedStoredText
|
|
377
|
-
})), "effect_agent_canonical_records", recordId, found).pipe(Effect.mapError(internalFailure(operation)));
|
|
396
|
+
const decoded = yield* decodeRows(CanonicalSettlementRows, "effect_agent_canonical_records", recordId, found).pipe(Effect.mapError(internalFailure(operation)));
|
|
378
397
|
if (decoded.length === 0) return void 0;
|
|
379
398
|
const row = decoded[0];
|
|
380
399
|
if (decoded.length !== 1 || row.batch_id !== submissionSettlementBatchId(expected.submissionId) || row.record_id !== recordId) return yield* corruptionFailure(operation, "effect_agent_canonical_records", recordId, "Canonical settlement identity is inconsistent.");
|
|
@@ -407,7 +426,7 @@ const makeServices = Effect.fnUntraced(function* () {
|
|
|
407
426
|
const childRow = yield* readSubmission(operation, childSubmissionId);
|
|
408
427
|
return Option.isSome(childRow) && (yield* readCanonicalSettlement(operation, childRow.value)) !== void 0;
|
|
409
428
|
});
|
|
410
|
-
const decodeChildReservationRows = (operation, rowKey, rows) => decodeRows(
|
|
429
|
+
const decodeChildReservationRows = (operation, rowKey, rows) => decodeRows(ChildReservationRows, "effect_agent_child_reservations", rowKey, rows).pipe(Effect.mapError(internalFailure(operation)));
|
|
411
430
|
const readChildReservation = Effect.fnUntraced(function* (operation, reservationId) {
|
|
412
431
|
const rows = yield* sql`
|
|
413
432
|
SELECT ${sql.literal(CHILD_RESERVATION_COLUMNS)}
|
|
@@ -480,9 +499,9 @@ const makeServices = Effect.fnUntraced(function* () {
|
|
|
480
499
|
});
|
|
481
500
|
});
|
|
482
501
|
const capabilities = Effect.succeed(LedgerCapabilities.make({ durability: "durable-cloudflare" }));
|
|
483
|
-
const admit = Effect.fnUntraced(function* (request) {
|
|
502
|
+
const admit = Effect.fnUntraced(function* (request, options) {
|
|
484
503
|
const operation = "ledger admit";
|
|
485
|
-
const validated = yield*
|
|
504
|
+
const validated = yield* decodeAdmissionRequestType(request).pipe(Effect.mapError(internalFailure(operation)));
|
|
486
505
|
const inputJson = yield* encodePersistedJsonText(validated.inputPayload).pipe(Effect.mapError(internalFailure(operation)));
|
|
487
506
|
yield* journal.checkValueBound(operation, inputJson).pipe(Effect.mapError(internalFailure(operation)));
|
|
488
507
|
const workerAdmissionJson = validated.workerAdmission === void 0 ? null : yield* Schema.encodeEffect(Schema.fromJsonString(WorkerAdmission))(validated.workerAdmission).pipe(Effect.mapError(internalFailure(operation)));
|
|
@@ -547,10 +566,10 @@ const makeServices = Effect.fnUntraced(function* () {
|
|
|
547
566
|
SELECT worker_admission_json FROM effect_agent_submissions
|
|
548
567
|
WHERE thread_id=${validated.threadId} ORDER BY queue_sequence LIMIT 1
|
|
549
568
|
`.pipe(Effect.mapError(sqlFailure(operation)));
|
|
550
|
-
const first = yield*
|
|
569
|
+
const first = yield* decodeFirstWorkerAdmissions(firstRows).pipe(Effect.mapError(internalFailure(operation)));
|
|
551
570
|
if (first[0] !== void 0) {
|
|
552
571
|
const previous = first[0].worker_admission_json === null ? void 0 : yield* Schema.decodeEffect(Schema.fromJsonString(WorkerAdmission))(first[0].worker_admission_json).pipe(Effect.mapError(internalFailure(operation)));
|
|
553
|
-
if (!
|
|
572
|
+
if (!equivalentWorkerOrigin(previous?.origin, validated.workerAdmission?.origin)) return yield* AdmissionPolicyError.make({
|
|
554
573
|
reason: "refused",
|
|
555
574
|
code: "worker-origin-conflict"
|
|
556
575
|
});
|
|
@@ -570,9 +589,10 @@ const makeServices = Effect.fnUntraced(function* () {
|
|
|
570
589
|
FROM effect_agent_submissions
|
|
571
590
|
WHERE thread_id = ${validated.threadId}
|
|
572
591
|
`.pipe(Effect.mapError(sqlFailure(operation)));
|
|
573
|
-
const decodedMax = yield* decodeRows(
|
|
592
|
+
const decodedMax = yield* decodeRows(MaxQueueSequenceRows, "effect_agent_submissions", validated.threadId, maxRows).pipe(Effect.mapError(internalFailure(operation)));
|
|
574
593
|
const queueSequence = yield* decodeQueueSequence((decodedMax[0]?.max_queue_sequence ?? 0) + 1).pipe(Effect.mapError(internalFailure(operation)));
|
|
575
594
|
const now = yield* currentInstant;
|
|
595
|
+
const ready = options?.readyIfInitialized === true && validated.workerAdmission === void 0 && (yield* journal.getThread(validated.threadId).pipe(Effect.mapError(internalFailure(operation)))).some((thread) => thread.tail_sequence > 0);
|
|
576
596
|
yield* sql`
|
|
577
597
|
INSERT INTO effect_agent_submissions (
|
|
578
598
|
submission_id,
|
|
@@ -588,6 +608,7 @@ const makeServices = Effect.fnUntraced(function* () {
|
|
|
588
608
|
receipt_id,
|
|
589
609
|
state,
|
|
590
610
|
created_at,
|
|
611
|
+
ready_at,
|
|
591
612
|
parent_submission_id,
|
|
592
613
|
parent_tool_call_id,
|
|
593
614
|
admission_group,
|
|
@@ -606,8 +627,9 @@ const makeServices = Effect.fnUntraced(function* () {
|
|
|
606
627
|
${inputJson},
|
|
607
628
|
${validated.inputDigest},
|
|
608
629
|
${mintedReceiptId},
|
|
609
|
-
|
|
630
|
+
${ready ? "ready" : "admitted"},
|
|
610
631
|
${now.iso},
|
|
632
|
+
${ready ? now.iso : null},
|
|
611
633
|
${validated.parentLinkage?.parentSubmissionId ?? null},
|
|
612
634
|
${validated.parentLinkage?.parentToolCallId ?? null},
|
|
613
635
|
${validated.admissionGroup ?? null},
|
|
@@ -619,6 +641,11 @@ const makeServices = Effect.fnUntraced(function* () {
|
|
|
619
641
|
if (queueSequence === 1) {
|
|
620
642
|
if ((yield* journal.getThread(validated.threadId).pipe(Effect.mapError(internalFailure(operation)))).length === 0) yield* journal.work.initialize(validated.threadId).pipe(Effect.mapError(internalFailure(operation)));
|
|
621
643
|
}
|
|
644
|
+
submissionViews.seedMatching(JSON.stringify([
|
|
645
|
+
"joining-suffix",
|
|
646
|
+
validated.threadId,
|
|
647
|
+
queueSequence
|
|
648
|
+
]), (row) => row.thread_id === validated.threadId && row.queue_sequence > queueSequence, [], 0);
|
|
622
649
|
rows.aborts.seed("submission_id", mintedSubmissionId, []);
|
|
623
650
|
rows.submissions.seed("joined_host_submission_id", mintedSubmissionId, []);
|
|
624
651
|
rows.approvals.seed("submission_id", mintedSubmissionId, []);
|
|
@@ -626,13 +653,18 @@ const makeServices = Effect.fnUntraced(function* () {
|
|
|
626
653
|
rows.childReservations.seed("parent_submission_id", mintedSubmissionId, []);
|
|
627
654
|
rows.childSettlements.seed("parent_submission_id", mintedSubmissionId, []);
|
|
628
655
|
yield* recordProgress("submission", operation);
|
|
629
|
-
|
|
656
|
+
const admitted = yield* decodeAdmissionResult({
|
|
630
657
|
submissionId: mintedSubmissionId,
|
|
631
658
|
receiptId: mintedReceiptId,
|
|
632
659
|
queueSequence,
|
|
633
|
-
state: "admitted",
|
|
660
|
+
state: ready ? "ready" : "admitted",
|
|
634
661
|
replayed: false
|
|
635
662
|
}).pipe(Effect.mapError(internalFailure(operation)));
|
|
663
|
+
if (ready && lifecycle !== void 0) yield* retainLifecycle(yield* requireSubmission(operation, mintedSubmissionId), {
|
|
664
|
+
_tag: "SubmissionReady",
|
|
665
|
+
submissionId: admitted.submissionId
|
|
666
|
+
});
|
|
667
|
+
return admitted;
|
|
636
668
|
}));
|
|
637
669
|
yield* hitFailpoint("ledger:admit:after", operation);
|
|
638
670
|
return result;
|
|
@@ -682,7 +714,7 @@ const makeServices = Effect.fnUntraced(function* () {
|
|
|
682
714
|
}, state.read);
|
|
683
715
|
const lookup = Effect.fnUntraced(function* (request) {
|
|
684
716
|
const operation = "ledger lookup";
|
|
685
|
-
const validated = yield*
|
|
717
|
+
const validated = yield* decodeSubmissionLookupType(request).pipe(Effect.mapError(internalFailure(operation)));
|
|
686
718
|
if (validated._tag === "SubmissionLookupById") {
|
|
687
719
|
const row = yield* readSubmission(operation, validated.submissionId);
|
|
688
720
|
if (Option.isNone(row)) return Option.none();
|
|
@@ -705,12 +737,23 @@ const makeServices = Effect.fnUntraced(function* () {
|
|
|
705
737
|
});
|
|
706
738
|
const selectHead = Effect.fn("DoSubmissionLedger.selectHead")(function* (request) {
|
|
707
739
|
const operation = "ledger select head";
|
|
708
|
-
const validated = yield*
|
|
740
|
+
const validated = yield* decodeClaimRequestType(request).pipe(Effect.mapError(internalFailure(operation)));
|
|
709
741
|
const attemptId = `attempt-${yield* mintUuid(operation)}`;
|
|
710
742
|
yield* hitFailpoint("ledger:claim:before", operation);
|
|
711
743
|
const claimed = yield* owner.withMutation(Effect.gen(function* () {
|
|
712
744
|
if (owner.hasOwner(validated.threadId)) return Option.none();
|
|
713
|
-
const
|
|
745
|
+
const active = yield* activeNonterminal;
|
|
746
|
+
const heads = [];
|
|
747
|
+
const limit = validated.handoff === void 0 ? 1 : validated.handoff.deferredSubmissionIds.length + 1;
|
|
748
|
+
if (active.length <= 128) {
|
|
749
|
+
const candidates = active.filter((row) => row.thread_id === validated.threadId).sort((left, right) => left.queue_sequence - right.queue_sequence);
|
|
750
|
+
for (const candidate of candidates) {
|
|
751
|
+
if (candidate.state === "unknown" && Option.isNone(yield* readAbortIntent(operation, candidate.submission_id))) continue;
|
|
752
|
+
heads.push(yield* requireSubmission(operation, candidate.submission_id));
|
|
753
|
+
if (heads.length === limit) break;
|
|
754
|
+
}
|
|
755
|
+
} else {
|
|
756
|
+
const headRows = yield* sql`
|
|
714
757
|
SELECT ${submissionColumns}
|
|
715
758
|
FROM effect_agent_submissions
|
|
716
759
|
WHERE thread_id = ${validated.threadId}
|
|
@@ -724,7 +767,8 @@ const makeServices = Effect.fnUntraced(function* () {
|
|
|
724
767
|
ORDER BY queue_sequence ASC
|
|
725
768
|
LIMIT ${validated.handoff === void 0 ? 1 : validated.handoff.deferredSubmissionIds.length + 1}
|
|
726
769
|
`.pipe(Effect.mapError(sqlFailure(operation)));
|
|
727
|
-
|
|
770
|
+
heads.push(...yield* decodeSubmissionRows(operation, validated.threadId, headRows));
|
|
771
|
+
}
|
|
728
772
|
if (heads.length === 0) return Option.none();
|
|
729
773
|
let head = heads[0];
|
|
730
774
|
if (validated.handoff !== void 0) {
|
|
@@ -751,7 +795,7 @@ const makeServices = Effect.fnUntraced(function* () {
|
|
|
751
795
|
});
|
|
752
796
|
const markInputApplied = Effect.fnUntraced(function* (request) {
|
|
753
797
|
const operation = "ledger mark input applied";
|
|
754
|
-
const validated = yield*
|
|
798
|
+
const validated = yield* decodeMarkInputAppliedRequestType(request).pipe(Effect.mapError(internalFailure(operation)));
|
|
755
799
|
yield* hitFailpoint("ledger:mark-input-applied:before", operation);
|
|
756
800
|
yield* inWriteTransaction(operation, Effect.gen(function* () {
|
|
757
801
|
const submission = yield* requireSubmission(operation, validated.submissionId);
|
|
@@ -896,7 +940,7 @@ const makeServices = Effect.fnUntraced(function* () {
|
|
|
896
940
|
});
|
|
897
941
|
const finalizeSettlement = Effect.fn("DoSubmissionLedger.finalizeSettlement")(function* (request) {
|
|
898
942
|
const operation = "ledger finalize settlement";
|
|
899
|
-
const validated = yield*
|
|
943
|
+
const validated = yield* decodeSettlementFinalizationType(request).pipe(Effect.mapError(internalFailure(operation)));
|
|
900
944
|
yield* hitFailpoint("ledger:finalize-settlement:before", operation);
|
|
901
945
|
const replay = yield* state.read(Effect.gen(function* () {
|
|
902
946
|
const submission = yield* readSubmission(operation, validated.submissionId);
|
|
@@ -1056,9 +1100,9 @@ const makeServices = Effect.fnUntraced(function* () {
|
|
|
1056
1100
|
});
|
|
1057
1101
|
const claimJoining = Effect.fnUntraced(function* (request) {
|
|
1058
1102
|
const operation = "ledger claim joining";
|
|
1059
|
-
const validated = yield*
|
|
1103
|
+
const validated = yield* decodeClaimJoiningRequestType(request).pipe(Effect.mapError(internalFailure(operation)));
|
|
1060
1104
|
yield* hitFailpoint("ledger:claim-joining:before", operation);
|
|
1061
|
-
const claims = yield*
|
|
1105
|
+
const claims = yield* owner.withMutation(Effect.gen(function* () {
|
|
1062
1106
|
const host = yield* requireSubmission(operation, validated.hostSubmissionId);
|
|
1063
1107
|
if (host.thread_id !== validated.threadId) return yield* LedgerError.make({
|
|
1064
1108
|
operation,
|
|
@@ -1066,36 +1110,42 @@ const makeServices = Effect.fnUntraced(function* () {
|
|
|
1066
1110
|
});
|
|
1067
1111
|
yield* requireOwner(operation, host);
|
|
1068
1112
|
if ((yield* cached(rows.workerStops.by("thread_id", validated.threadId), operation)).length > 0) return [];
|
|
1069
|
-
const
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
const
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1113
|
+
const later = yield* submissionViews.matching(JSON.stringify([
|
|
1114
|
+
"joining-suffix",
|
|
1115
|
+
validated.threadId,
|
|
1116
|
+
host.queue_sequence
|
|
1117
|
+
]), (row) => row.thread_id === validated.threadId && row.queue_sequence > host.queue_sequence, sql`
|
|
1118
|
+
SELECT ${submissionColumns}
|
|
1119
|
+
FROM effect_agent_submissions
|
|
1120
|
+
WHERE thread_id = ${validated.threadId}
|
|
1121
|
+
AND queue_sequence > ${host.queue_sequence}
|
|
1122
|
+
ORDER BY queue_sequence ASC
|
|
1123
|
+
`, 0).pipe(Effect.mapError((error) => error._tag === "SqlError" ? sqlFailure(operation)(error) : internalFailure(operation)(error)));
|
|
1124
|
+
if (later.length === 0) return [];
|
|
1125
|
+
return yield* inWriteTransaction(operation, Effect.gen(function* () {
|
|
1126
|
+
const claimed = [];
|
|
1127
|
+
for (const row of later) {
|
|
1128
|
+
if (claimed.length >= validated.maxCount) break;
|
|
1129
|
+
if ((row.state === "joining" || row.state === "joined") && row.joined_host_submission_id === validated.hostSubmissionId) continue;
|
|
1130
|
+
if (row.state === "settled" && row.settled_outcome === "aborted") continue;
|
|
1131
|
+
if (row.state !== "ready") break;
|
|
1132
|
+
const canonical = yield* readCanonicalSettlement(operation, row);
|
|
1133
|
+
if (canonical?.settlement.outcome === "aborted") continue;
|
|
1134
|
+
if (canonical !== void 0) break;
|
|
1135
|
+
yield* sql`
|
|
1087
1136
|
UPDATE effect_agent_submissions
|
|
1088
1137
|
SET state = 'joining', joined_host_submission_id = ${validated.hostSubmissionId}
|
|
1089
1138
|
WHERE submission_id = ${row.submission_id}
|
|
1090
1139
|
RETURNING *, ${definitionJson(sql)} AS agent_digests_json`.pipe(rows.submissions.write, Effect.mapError(internalFailure(operation)));
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1140
|
+
const inputPayload = yield* parseStoredJsonText(row.input_json).pipe(Effect.mapError((error) => corruptionFailure(operation, "effect_agent_submissions", row.submission_id, error.message)));
|
|
1141
|
+
claimed.push(yield* decodeJoiningClaim({
|
|
1142
|
+
submissionId: row.submission_id,
|
|
1143
|
+
queueSequence: row.queue_sequence,
|
|
1144
|
+
inputPayload
|
|
1145
|
+
}).pipe(Effect.mapError(internalFailure(operation))));
|
|
1146
|
+
}
|
|
1147
|
+
return claimed;
|
|
1148
|
+
}));
|
|
1099
1149
|
}));
|
|
1100
1150
|
yield* hitFailpoint("ledger:claim-joining:after", operation);
|
|
1101
1151
|
return claims;
|
|
@@ -1665,20 +1715,21 @@ const makeServices = Effect.fnUntraced(function* () {
|
|
|
1665
1715
|
ORDER BY thread_id ASC, queue_sequence ASC
|
|
1666
1716
|
LIMIT ${SCAN_PAGE_SIZE}
|
|
1667
1717
|
`).pipe(Effect.mapError(sqlFailure(operation)));
|
|
1668
|
-
const decoded = yield* decodeRows(
|
|
1718
|
+
const decoded = yield* decodeRows(SubmissionWorkItems, "effect_agent_submissions", "nonterminal_scan", rows, "SubmissionWorkItem").pipe(Effect.mapError(internalFailure(operation)));
|
|
1669
1719
|
const last = decoded[decoded.length - 1];
|
|
1670
1720
|
return [decoded, last === void 0 || decoded.length < SCAN_PAGE_SIZE ? Option.none() : Option.some({
|
|
1671
1721
|
threadId: last.threadId,
|
|
1672
1722
|
queueSequence: last.queueSequence
|
|
1673
1723
|
})];
|
|
1674
1724
|
});
|
|
1675
|
-
const
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1725
|
+
const activeNonterminal = cached(workRows.matching("nonterminal", (row) => row.state !== "settled", sql`SELECT submission_id, thread_id, queue_sequence, principal, idempotency_key,
|
|
1726
|
+
deployment_id, receipt_id, state
|
|
1727
|
+
FROM effect_agent_submissions WHERE state <> 'settled' LIMIT 129`, 128), "ledger scan nonterminal");
|
|
1728
|
+
const boundedNonterminal = state.read(Effect.gen(function* () {
|
|
1729
|
+
const active = yield* activeNonterminal;
|
|
1730
|
+
if (active.length > 128) return void 0;
|
|
1680
1731
|
const sorted = [...active].sort((left, right) => left.thread_id < right.thread_id ? -1 : left.thread_id > right.thread_id ? 1 : left.queue_sequence - right.queue_sequence);
|
|
1681
|
-
|
|
1732
|
+
return yield* decodeSubmissionWorkItems(sorted.map((row) => ({
|
|
1682
1733
|
submissionId: row.submission_id,
|
|
1683
1734
|
threadId: row.thread_id,
|
|
1684
1735
|
queueSequence: row.queue_sequence,
|
|
@@ -1688,11 +1739,13 @@ const makeServices = Effect.fnUntraced(function* () {
|
|
|
1688
1739
|
receiptId: row.receipt_id,
|
|
1689
1740
|
state: row.state
|
|
1690
1741
|
}))).pipe(Effect.mapError(internalFailure("ledger scan nonterminal")));
|
|
1691
|
-
|
|
1692
|
-
|
|
1742
|
+
}));
|
|
1743
|
+
const pagedNonterminal = Stream.paginate(void 0, scanPage);
|
|
1744
|
+
const scanNonterminal = Stream.unwrap(Effect.map(boundedNonterminal, (work) => work === void 0 ? pagedNonterminal : Stream.fromIterable(work)));
|
|
1745
|
+
const listNonterminal = Effect.filterOrElse(boundedNonterminal, (work) => work !== void 0, () => Stream.runCollect(pagedNonterminal));
|
|
1693
1746
|
const readAbortIntentForSubmission = Effect.fnUntraced(function* (request) {
|
|
1694
1747
|
const operation = "ledger read abort intent";
|
|
1695
|
-
const validated = yield*
|
|
1748
|
+
const validated = yield* decodeAbortIntentRequestType(request).pipe(Effect.mapError(internalFailure(operation)));
|
|
1696
1749
|
return yield* state.read(Effect.gen(function* () {
|
|
1697
1750
|
const submission = yield* requireSubmission(operation, validated.submissionId);
|
|
1698
1751
|
const intent = yield* readAbortIntent(operation, validated.submissionId);
|
|
@@ -1701,7 +1754,7 @@ const makeServices = Effect.fnUntraced(function* () {
|
|
|
1701
1754
|
});
|
|
1702
1755
|
const loadRecoverySnapshot = Effect.fnUntraced(function* (request) {
|
|
1703
1756
|
const operation = "ledger load recovery snapshot";
|
|
1704
|
-
const validated = yield*
|
|
1757
|
+
const validated = yield* decodeRecoverySnapshotRequestType(request).pipe(Effect.mapError(internalFailure(operation)));
|
|
1705
1758
|
return yield* state.read(Effect.gen(function* () {
|
|
1706
1759
|
const submissionRow = yield* requireSubmission(operation, validated.submissionId);
|
|
1707
1760
|
const submission = yield* decodeSubmissionSnapshot(operation, submissionRow);
|
|
@@ -1808,6 +1861,7 @@ const makeServices = Effect.fnUntraced(function* () {
|
|
|
1808
1861
|
beginChildBudgetRelease,
|
|
1809
1862
|
releaseChildBudget,
|
|
1810
1863
|
scanNonterminal,
|
|
1864
|
+
listNonterminal,
|
|
1811
1865
|
loadRecoverySnapshot,
|
|
1812
1866
|
readAbortIntent: readAbortIntentForSubmission
|
|
1813
1867
|
})).pipe(Context.add(StorageOwner, owner), Context.add(SettlementPublisher, { publish }));
|