@usine/executor 0.2.0 → 0.3.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/README.md +115 -37
- package/dist/child-command.d.ts +4 -7
- package/dist/child-command.d.ts.map +1 -1
- package/dist/child-command.js +6 -12
- package/dist/child-command.js.map +1 -1
- package/dist/claude-login-lock.d.ts +8 -0
- package/dist/claude-login-lock.d.ts.map +1 -0
- package/dist/claude-login-lock.js +9 -0
- package/dist/claude-login-lock.js.map +1 -0
- package/dist/credential-environment.d.ts +20 -0
- package/dist/credential-environment.d.ts.map +1 -0
- package/dist/credential-environment.js +20 -0
- package/dist/credential-environment.js.map +1 -0
- package/dist/durable-session.d.ts +63 -0
- package/dist/durable-session.d.ts.map +1 -0
- package/dist/durable-session.js +491 -0
- package/dist/durable-session.js.map +1 -0
- package/dist/exe-dev/commands.d.ts +23 -13
- package/dist/exe-dev/commands.d.ts.map +1 -1
- package/dist/exe-dev/commands.js +11 -57
- package/dist/exe-dev/commands.js.map +1 -1
- package/dist/exe-dev/exe-dev.d.ts +9 -3
- package/dist/exe-dev/exe-dev.d.ts.map +1 -1
- package/dist/exe-dev/exe-dev.js +53 -127
- package/dist/exe-dev/exe-dev.js.map +1 -1
- package/dist/exe-dev/grants.d.ts.map +1 -1
- package/dist/exe-dev/grants.js +35 -15
- package/dist/exe-dev/grants.js.map +1 -1
- package/dist/exe-dev/model.d.ts +15 -19
- package/dist/exe-dev/model.d.ts.map +1 -1
- package/dist/exe-dev/model.js +9 -12
- package/dist/exe-dev/model.js.map +1 -1
- package/dist/exe-dev/preflight.d.ts +8 -4
- package/dist/exe-dev/preflight.d.ts.map +1 -1
- package/dist/exe-dev/preflight.js +23 -33
- package/dist/exe-dev/preflight.js.map +1 -1
- package/dist/executor.d.ts +141 -38
- package/dist/executor.d.ts.map +1 -1
- package/dist/executor.js +90 -17
- package/dist/executor.js.map +1 -1
- package/dist/guard.d.ts +61 -0
- package/dist/guard.d.ts.map +1 -0
- package/dist/guard.js +288 -0
- package/dist/guard.js.map +1 -0
- package/dist/harness-preflight.d.ts +25 -4
- package/dist/harness-preflight.d.ts.map +1 -1
- package/dist/harness-preflight.js +25 -29
- package/dist/harness-preflight.js.map +1 -1
- package/dist/keyed-lock.d.ts +2 -3
- package/dist/keyed-lock.d.ts.map +1 -1
- package/dist/keyed-lock.js +2 -3
- package/dist/keyed-lock.js.map +1 -1
- package/dist/leftovers.d.ts +9 -0
- package/dist/leftovers.d.ts.map +1 -0
- package/dist/leftovers.js +14 -0
- package/dist/leftovers.js.map +1 -0
- package/dist/local/credentials.d.ts +21 -0
- package/dist/local/credentials.d.ts.map +1 -0
- package/dist/local/credentials.js +39 -0
- package/dist/local/credentials.js.map +1 -0
- package/dist/local/leftovers.d.ts +8 -0
- package/dist/local/leftovers.d.ts.map +1 -0
- package/dist/local/leftovers.js +23 -0
- package/dist/local/leftovers.js.map +1 -0
- package/dist/local/local.d.ts +16 -10
- package/dist/local/local.d.ts.map +1 -1
- package/dist/local/local.js +164 -129
- package/dist/local/local.js.map +1 -1
- package/dist/memory-preflight.d.ts +25 -0
- package/dist/memory-preflight.d.ts.map +1 -0
- package/dist/memory-preflight.js +83 -0
- package/dist/memory-preflight.js.map +1 -0
- package/dist/pre-push-hook.d.ts +20 -0
- package/dist/pre-push-hook.d.ts.map +1 -0
- package/dist/pre-push-hook.js +33 -0
- package/dist/pre-push-hook.js.map +1 -0
- package/dist/prepared-attempt.d.ts +33 -3
- package/dist/prepared-attempt.d.ts.map +1 -1
- package/dist/prepared-attempt.js +109 -39
- package/dist/prepared-attempt.js.map +1 -1
- package/dist/provision.d.ts +77 -14
- package/dist/provision.d.ts.map +1 -1
- package/dist/provision.js +357 -55
- package/dist/provision.js.map +1 -1
- package/dist/remote/commands.d.ts +51 -0
- package/dist/remote/commands.d.ts.map +1 -0
- package/dist/remote/commands.js +94 -0
- package/dist/remote/commands.js.map +1 -0
- package/dist/remote/leftovers.d.ts +14 -0
- package/dist/remote/leftovers.d.ts.map +1 -0
- package/dist/remote/leftovers.js +22 -0
- package/dist/remote/leftovers.js.map +1 -0
- package/dist/remote/liveness.d.ts +33 -0
- package/dist/remote/liveness.d.ts.map +1 -0
- package/dist/remote/liveness.js +194 -0
- package/dist/remote/liveness.js.map +1 -0
- package/dist/remote/machine.d.ts +64 -0
- package/dist/remote/machine.d.ts.map +1 -0
- package/dist/remote/machine.js +2 -0
- package/dist/remote/machine.js.map +1 -0
- package/dist/remote/remote.d.ts +24 -0
- package/dist/remote/remote.d.ts.map +1 -0
- package/dist/remote/remote.js +308 -0
- package/dist/remote/remote.js.map +1 -0
- package/dist/remote/sweep.d.ts +15 -0
- package/dist/remote/sweep.d.ts.map +1 -0
- package/dist/remote/sweep.js +116 -0
- package/dist/remote/sweep.js.map +1 -0
- package/dist/renewable-credential.d.ts +17 -0
- package/dist/renewable-credential.d.ts.map +1 -0
- package/dist/renewable-credential.js +58 -0
- package/dist/renewable-credential.js.map +1 -0
- package/dist/salvage.d.ts +30 -0
- package/dist/salvage.d.ts.map +1 -0
- package/dist/salvage.js +104 -0
- package/dist/salvage.js.map +1 -0
- package/dist/ssh/credentials.d.ts +40 -0
- package/dist/ssh/credentials.d.ts.map +1 -0
- package/dist/ssh/credentials.js +83 -0
- package/dist/ssh/credentials.js.map +1 -0
- package/dist/ssh/gateway/admin.d.ts +45 -0
- package/dist/ssh/gateway/admin.d.ts.map +1 -0
- package/dist/ssh/gateway/admin.js +129 -0
- package/dist/ssh/gateway/admin.js.map +1 -0
- package/dist/ssh/gateway/attachments.d.ts +22 -0
- package/dist/ssh/gateway/attachments.d.ts.map +1 -0
- package/dist/ssh/gateway/attachments.js +154 -0
- package/dist/ssh/gateway/attachments.js.map +1 -0
- package/dist/ssh/gateway/environment.d.ts +52 -0
- package/dist/ssh/gateway/environment.d.ts.map +1 -0
- package/dist/ssh/gateway/environment.js +78 -0
- package/dist/ssh/gateway/environment.js.map +1 -0
- package/dist/ssh/gateway/forward.d.ts +74 -0
- package/dist/ssh/gateway/forward.d.ts.map +1 -0
- package/dist/ssh/gateway/forward.js +247 -0
- package/dist/ssh/gateway/forward.js.map +1 -0
- package/dist/ssh/gateway/preflight.d.ts +28 -0
- package/dist/ssh/gateway/preflight.d.ts.map +1 -0
- package/dist/ssh/gateway/preflight.js +234 -0
- package/dist/ssh/gateway/preflight.js.map +1 -0
- package/dist/ssh/model.d.ts +65 -0
- package/dist/ssh/model.d.ts.map +1 -0
- package/dist/ssh/model.js +2 -0
- package/dist/ssh/model.js.map +1 -0
- package/dist/ssh/preflight.d.ts +16 -0
- package/dist/ssh/preflight.d.ts.map +1 -0
- package/dist/ssh/preflight.js +47 -0
- package/dist/ssh/preflight.js.map +1 -0
- package/dist/ssh/ssh.d.ts +20 -0
- package/dist/ssh/ssh.d.ts.map +1 -0
- package/dist/ssh/ssh.js +78 -0
- package/dist/ssh/ssh.js.map +1 -0
- package/dist/ssh/workers.d.ts +53 -0
- package/dist/ssh/workers.d.ts.map +1 -0
- package/dist/ssh/workers.js +173 -0
- package/dist/ssh/workers.js.map +1 -0
- package/package.json +12 -4
- package/dist/exe-dev/channel.d.ts +0 -11
- package/dist/exe-dev/channel.d.ts.map +0 -1
- package/dist/exe-dev/channel.js +0 -41
- package/dist/exe-dev/channel.js.map +0 -1
- package/dist/exe-dev/shell.d.ts +0 -12
- package/dist/exe-dev/shell.d.ts.map +0 -1
- package/dist/exe-dev/shell.js +0 -31
- package/dist/exe-dev/shell.js.map +0 -1
- package/dist/exe-dev/sweep.d.ts +0 -10
- package/dist/exe-dev/sweep.d.ts.map +0 -1
- package/dist/exe-dev/sweep.js +0 -117
- package/dist/exe-dev/sweep.js.map +0 -1
- package/dist/invalid-frame.d.ts +0 -17
- package/dist/invalid-frame.d.ts.map +0 -1
- package/dist/invalid-frame.js +0 -111
- package/dist/invalid-frame.js.map +0 -1
- package/dist/run-host-session.d.ts +0 -26
- package/dist/run-host-session.d.ts.map +0 -1
- package/dist/run-host-session.js +0 -241
- package/dist/run-host-session.js.map +0 -1
package/dist/executor.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"executor.js","sourceRoot":"","sources":["../src/executor.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"executor.js","sourceRoot":"","sources":["../src/executor.ts"],"names":[],"mappings":"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"}
|
package/dist/guard.d.ts
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import type { AttemptId } from "@usine/core/attempt";
|
|
2
|
+
import type { AgentSessionId } from "@usine/core/agent/session";
|
|
3
|
+
import type * as AttemptChannel from "@usine/core/attempt/channel";
|
|
4
|
+
import { AttemptFailure, RunawayCeiling, RunawayFailure } from "@usine/core/attempt/failure";
|
|
5
|
+
import { Duration, Effect, Option } from "effect";
|
|
6
|
+
export interface AttemptGuardLimits {
|
|
7
|
+
readonly attemptId: AttemptId;
|
|
8
|
+
/** The wall-clock ceiling in minutes, or `None` for no limit. */
|
|
9
|
+
readonly maxAttemptMinutes: Option.Option<number>;
|
|
10
|
+
/** The token ceiling across the parent and all children, or `None` for no limit. */
|
|
11
|
+
readonly maxAttemptTokens: Option.Option<number>;
|
|
12
|
+
/**
|
|
13
|
+
* Sends the warning steer to the parent session. Can wait for the parent's channel without
|
|
14
|
+
* delaying the ceiling checks; failures are logged and don't fail the Attempt.
|
|
15
|
+
*/
|
|
16
|
+
readonly warn: (message: string) => Effect.Effect<void, AttemptFailure>;
|
|
17
|
+
/**
|
|
18
|
+
* Persists the unsupervised time counted so far, including the seed, for a later reattachment.
|
|
19
|
+
* Called every `RECORD_INTERVAL` while the count grows and once on stop; failures are logged.
|
|
20
|
+
*/
|
|
21
|
+
readonly recordUnsupervised: (unsupervised: Duration.Duration) => Effect.Effect<void, AttemptFailure>;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* The counts restored from earlier guards, so a reattached Attempt's guard continues instead of
|
|
25
|
+
* starting over (#178). Empty for a new Attempt.
|
|
26
|
+
*/
|
|
27
|
+
export interface AttemptGuardSeed {
|
|
28
|
+
/** The highest token count each session reported, including sessions that finished before the restart. */
|
|
29
|
+
readonly tokens: ReadonlyMap<AgentSessionId, number>;
|
|
30
|
+
/** The unsupervised time recorded by earlier guards, excluding time the orchestrator was stopped. */
|
|
31
|
+
readonly unsupervised: Duration.Duration;
|
|
32
|
+
/** Whether the parent was on Hold at the restart. A parent's Hold persists across restarts; a child's doesn't. */
|
|
33
|
+
readonly parentHeld: boolean;
|
|
34
|
+
/** The ceilings whose warning steer is already in the transcript. */
|
|
35
|
+
readonly warned: ReadonlySet<RunawayCeiling>;
|
|
36
|
+
}
|
|
37
|
+
/** Returns a reattached guard's seed from `unsupervised` and the transcript `envelopes` in append order. */
|
|
38
|
+
export declare const guardSeed: (transcript: ReadonlyArray<AttemptChannel.Envelope>, unsupervised: Duration.Duration) => AttemptGuardSeed;
|
|
39
|
+
export interface AttemptGuard {
|
|
40
|
+
/**
|
|
41
|
+
* The Attempt's sink, wrapped. The append that reaches the token ceiling fails with
|
|
42
|
+
* `RunawayFailure`. An append that reaches the warning point queues the warning for `tripped`
|
|
43
|
+
* without waiting, because awaiting delivery inside `append` would deadlock.
|
|
44
|
+
*/
|
|
45
|
+
readonly sink: AttemptChannel.Sink;
|
|
46
|
+
/**
|
|
47
|
+
* Checks the restored token total, counts unsupervised time, and sends queued warnings through
|
|
48
|
+
* `limits.warn`. Fails with `RunawayFailure` when the restored token total or the wall-clock
|
|
49
|
+
* ceiling trips; never succeeds. On interruption, records the counted time within
|
|
50
|
+
* `LAST_RECORD_GRACE`.
|
|
51
|
+
*/
|
|
52
|
+
readonly tripped: Effect.Effect<never, RunawayFailure>;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Arms the configured Attempt ceilings, each with one warning steer at `WARNING_FRACTION` of
|
|
56
|
+
* its limit. Holds pause the wall clock; tokens keep accumulating. Counts continue from `seed`,
|
|
57
|
+
* so a reattached Attempt trips at the same totals as without the restart. With no ceiling set,
|
|
58
|
+
* `sink` is `io` and `tripped` never completes.
|
|
59
|
+
*/
|
|
60
|
+
export declare const attemptGuard: (limits: AttemptGuardLimits, io: AttemptChannel.Sink, seed: AttemptGuardSeed) => Effect.Effect<AttemptGuard>;
|
|
61
|
+
//# sourceMappingURL=guard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"guard.d.ts","sourceRoot":"","sources":["../src/guard.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,KAAK,EAAgB,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC9E,OAAO,KAAK,KAAK,cAAc,MAAM,6BAA6B,CAAC;AACnE,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7F,OAAO,EAAS,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAS,MAAM,QAAQ,CAAC;AAyBhE,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;IAC9B,iEAAiE;IACjE,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAClD,oFAAoF;IACpF,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACjD;;;OAGG;IACH,QAAQ,CAAC,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC;IACxE;;;OAGG;IACH,QAAQ,CAAC,kBAAkB,EAAE,CAC3B,YAAY,EAAE,QAAQ,CAAC,QAAQ,KAC5B,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC;CAC1C;AAED;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC/B,0GAA0G;IAC1G,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC;IACrD,qGAAqG;IACrG,QAAQ,CAAC,YAAY,EAAE,QAAQ,CAAC,QAAQ,CAAC;IACzC,kHAAkH;IAClH,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;IAC7B,qEAAqE;IACrE,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC,cAAc,CAAC,CAAC;CAC9C;AA8ED,4GAA4G;AAC5G,eAAO,MAAM,SAAS,eACR,aAAa,CAAC,cAAc,CAAC,QAAQ,CAAC,gBACpC,QAAQ,CAAC,QAAQ,KAC9B,gBAYF,CAAC;AAsLF,MAAM,WAAW,YAAY;IAC3B;;;;OAIG;IACH,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAC,IAAI,CAAC;IACnC;;;;;OAKG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,cAAc,CAAC,CAAC;CACxD;AAED;;;;;GAKG;AACH,eAAO,MAAM,YAAY,WACf,kBAAkB,MACtB,cAAc,CAAC,IAAI,QACjB,gBAAgB,KACrB,MAAM,CAAC,MAAM,CAAC,YAAY,CA4E5B,CAAC"}
|
package/dist/guard.js
ADDED
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
import { AttemptFailure, RunawayCeiling, RunawayFailure } from "@usine/core/attempt/failure";
|
|
2
|
+
import { Clock, Duration, Effect, Option, Queue } from "effect";
|
|
3
|
+
/** The fraction of a ceiling at which the parent gets one warning steer. */
|
|
4
|
+
const WARNING_FRACTION = 0.8;
|
|
5
|
+
/**
|
|
6
|
+
* The interval for recording unsupervised time while it grows. An orchestrator that exits
|
|
7
|
+
* without shutting down loses at most this much (#178).
|
|
8
|
+
*/
|
|
9
|
+
const RECORD_INTERVAL = Duration.seconds(30);
|
|
10
|
+
/** The timeout for the final unsupervised-time record when the guard stops. */
|
|
11
|
+
const LAST_RECORD_GRACE = Duration.seconds(5);
|
|
12
|
+
/** The suffix of every warning steer, after the ceiling's unit. */
|
|
13
|
+
const WARNING_ENDING = "used by this Attempt; commit and push your work now.";
|
|
14
|
+
const WARNING_UNITS = {
|
|
15
|
+
tokens: "tokens",
|
|
16
|
+
"wall-clock": "minutes",
|
|
17
|
+
};
|
|
18
|
+
const warning = (ceiling, used, limit) => `${used} of ${limit} ${WARNING_UNITS[ceiling]} ${WARNING_ENDING}`;
|
|
19
|
+
const ceiling = (limit) => ({ limit, warnAt: limit * WARNING_FRACTION });
|
|
20
|
+
/** Stores the session's token count from `envelope` if higher, because reports are cumulative. Returns whether `envelope` was a token report. */
|
|
21
|
+
const recordTokens = (reported, envelope) => {
|
|
22
|
+
const payload = envelope.payload;
|
|
23
|
+
if (payload._tag !== "SessionEvent" || payload.event._tag !== "SessionTokensUpdated")
|
|
24
|
+
return false;
|
|
25
|
+
const { session, totalTokens } = payload.event;
|
|
26
|
+
reported.set(session.id, Math.max(reported.get(session.id) ?? 0, totalTokens));
|
|
27
|
+
return true;
|
|
28
|
+
};
|
|
29
|
+
/** Returns the Hold key: `"parent"` for the parent session, or the session ID for a child. */
|
|
30
|
+
const holdKey = (session) => {
|
|
31
|
+
switch (session._tag) {
|
|
32
|
+
case "Parent":
|
|
33
|
+
case "ParentSession":
|
|
34
|
+
return "parent";
|
|
35
|
+
case "Child":
|
|
36
|
+
return session.sessionId;
|
|
37
|
+
case "ChildSession":
|
|
38
|
+
return session.id;
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
/**
|
|
42
|
+
* Updates the held sessions from `envelope`. An intervention receipt places or removes its
|
|
43
|
+
* target's Hold; a finished session is never held again, so a late receipt is ignored.
|
|
44
|
+
*/
|
|
45
|
+
const recordHolds = (holds, ended, envelope) => {
|
|
46
|
+
const payload = envelope.payload;
|
|
47
|
+
if (payload._tag === "InterventionApplied") {
|
|
48
|
+
const key = holdKey(payload.intervention.target);
|
|
49
|
+
if (payload.state.held && !ended.has(key))
|
|
50
|
+
holds.add(key);
|
|
51
|
+
else
|
|
52
|
+
holds.delete(key);
|
|
53
|
+
}
|
|
54
|
+
if (payload._tag === "SessionEvent" && payload.event._tag === "SessionFinished") {
|
|
55
|
+
const key = holdKey(payload.event.session);
|
|
56
|
+
ended.add(key);
|
|
57
|
+
holds.delete(key);
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
/** Returns the ceiling whose warning steer `envelope` is: a parent steer that ends with the ceiling's unit and `WARNING_ENDING`. */
|
|
61
|
+
const warnedCeiling = (envelope) => {
|
|
62
|
+
if (envelope._tag !== "InboundEnvelope" ||
|
|
63
|
+
envelope.target._tag !== "Parent" ||
|
|
64
|
+
envelope.payload._tag !== "Steer") {
|
|
65
|
+
return Option.none();
|
|
66
|
+
}
|
|
67
|
+
const message = envelope.payload.message;
|
|
68
|
+
return Option.fromNullishOr(RunawayCeiling.literals.find((ceiling) => message.endsWith(` ${WARNING_UNITS[ceiling]} ${WARNING_ENDING}`)));
|
|
69
|
+
};
|
|
70
|
+
/** Returns a reattached guard's seed from `unsupervised` and the transcript `envelopes` in append order. */
|
|
71
|
+
export const guardSeed = (transcript, unsupervised) => {
|
|
72
|
+
const tokens = new Map();
|
|
73
|
+
const warned = new Set();
|
|
74
|
+
const holds = new Set();
|
|
75
|
+
const ended = new Set();
|
|
76
|
+
for (const envelope of transcript) {
|
|
77
|
+
recordHolds(holds, ended, envelope);
|
|
78
|
+
recordTokens(tokens, envelope);
|
|
79
|
+
const sent = warnedCeiling(envelope);
|
|
80
|
+
if (Option.isSome(sent))
|
|
81
|
+
warned.add(sent.value);
|
|
82
|
+
}
|
|
83
|
+
return { tokens, unsupervised, parentHeld: holds.has("parent"), warned };
|
|
84
|
+
};
|
|
85
|
+
/**
|
|
86
|
+
* Returns a watcher that sums the highest reported count per session, including the seed;
|
|
87
|
+
* Holds don't pause it. `resume` checks the restored total immediately, so it can warn or trip
|
|
88
|
+
* without another report (#178).
|
|
89
|
+
*/
|
|
90
|
+
const tokenWatcher = (attemptId, tokens, warn, seed) => {
|
|
91
|
+
const reported = new Map(seed.tokens);
|
|
92
|
+
let warned = seed.warned.has("tokens");
|
|
93
|
+
/** Trips at the limit, or warns once past the warning point. Returns the total. */
|
|
94
|
+
const check = Effect.gen(function* () {
|
|
95
|
+
const consumed = [...reported.values()].reduce((sum, value) => sum + value, 0);
|
|
96
|
+
if (consumed >= tokens.limit) {
|
|
97
|
+
yield* Effect.logWarning("Attempt reached its token limit", {
|
|
98
|
+
attemptId,
|
|
99
|
+
consumed,
|
|
100
|
+
maxAttemptTokens: tokens.limit,
|
|
101
|
+
});
|
|
102
|
+
return yield* new RunawayFailure({ ceiling: "tokens" });
|
|
103
|
+
}
|
|
104
|
+
if (!warned && consumed >= tokens.warnAt) {
|
|
105
|
+
warned = true;
|
|
106
|
+
yield* warn("tokens", warning("tokens", consumed, tokens.limit));
|
|
107
|
+
}
|
|
108
|
+
return consumed;
|
|
109
|
+
});
|
|
110
|
+
const observe = (envelope) => recordTokens(reported, envelope) ? Effect.asVoid(check) : Effect.void;
|
|
111
|
+
const resume = Effect.gen(function* () {
|
|
112
|
+
yield* Effect.annotateCurrentSpan({ attemptId });
|
|
113
|
+
const consumed = yield* check;
|
|
114
|
+
yield* Effect.logDebug("Attempt token total is under its limit as its guard starts", {
|
|
115
|
+
attemptId,
|
|
116
|
+
consumed,
|
|
117
|
+
maxAttemptTokens: tokens.limit,
|
|
118
|
+
warned,
|
|
119
|
+
});
|
|
120
|
+
}).pipe(Effect.withSpan("AttemptGuard.resumeTokens"));
|
|
121
|
+
return { observe, resume };
|
|
122
|
+
};
|
|
123
|
+
/**
|
|
124
|
+
* Returns a watcher that counts unsupervised milliseconds on top of the seed, paused while any
|
|
125
|
+
* session is held. `watch` warns at the warning point unless the warning is already in the
|
|
126
|
+
* transcript, then trips at the limit. While running, it records the count every
|
|
127
|
+
* `RECORD_INTERVAL` if it grew, and once more on interruption (#178).
|
|
128
|
+
*/
|
|
129
|
+
const wallClockWatcher = Effect.fn("AttemptGuard.wallClockWatcher")(function* (attemptId, wallClock, warn, record, seed) {
|
|
130
|
+
const ended = new Set();
|
|
131
|
+
const holds = new Set(seed.parentHeld ? ["parent"] : []);
|
|
132
|
+
/** Signals `watch` when supervision changes; one pending signal is enough. */
|
|
133
|
+
const changed = yield* Queue.sliding(1);
|
|
134
|
+
/** Whether `watch` has started; nothing is counted before. */
|
|
135
|
+
let watching = false;
|
|
136
|
+
/** The unsupervised milliseconds of completed intervals, including the seed. */
|
|
137
|
+
let counted = Duration.toMillis(seed.unsupervised);
|
|
138
|
+
/** The start of the current unsupervised interval, or `None` while held or before `watch` runs. */
|
|
139
|
+
let since = Option.none();
|
|
140
|
+
/** The unsupervised milliseconds last persisted, initially the seed's. */
|
|
141
|
+
let recorded = counted;
|
|
142
|
+
const usedAt = (now) => counted + Option.match(since, { onNone: () => 0, onSome: (began) => now - began });
|
|
143
|
+
/**
|
|
144
|
+
* Applies the current Holds at `now`: a Hold ends the current interval, and a release while
|
|
145
|
+
* `watch` runs starts one.
|
|
146
|
+
*/
|
|
147
|
+
const supervise = (now) => {
|
|
148
|
+
if (holds.size > 0) {
|
|
149
|
+
counted = usedAt(now);
|
|
150
|
+
since = Option.none();
|
|
151
|
+
}
|
|
152
|
+
else if (watching && Option.isNone(since)) {
|
|
153
|
+
since = Option.some(now);
|
|
154
|
+
}
|
|
155
|
+
};
|
|
156
|
+
const observe = (envelope) => Effect.gen(function* () {
|
|
157
|
+
const wasHeld = holds.size > 0;
|
|
158
|
+
recordHolds(holds, ended, envelope);
|
|
159
|
+
const isHeld = holds.size > 0;
|
|
160
|
+
if (wasHeld === isHeld)
|
|
161
|
+
return;
|
|
162
|
+
supervise(yield* Clock.currentTimeMillis);
|
|
163
|
+
yield* Effect.logInfo("Attempt wall-clock supervision changed", {
|
|
164
|
+
attemptId,
|
|
165
|
+
heldSessions: holds.size,
|
|
166
|
+
parentHeld: holds.has("parent"),
|
|
167
|
+
unsupervisedMillis: counted,
|
|
168
|
+
});
|
|
169
|
+
yield* Queue.offer(changed, undefined);
|
|
170
|
+
});
|
|
171
|
+
/** Waits until `until` unsupervised milliseconds are counted and returns the count. Never returns while held. */
|
|
172
|
+
const unsupervised = Effect.fn("AttemptGuard.unsupervised")(function* (until) {
|
|
173
|
+
yield* Effect.annotateCurrentSpan({ attemptId, untilMillis: until });
|
|
174
|
+
for (;;) {
|
|
175
|
+
if (holds.size > 0) {
|
|
176
|
+
yield* Queue.take(changed);
|
|
177
|
+
continue;
|
|
178
|
+
}
|
|
179
|
+
const used = usedAt(yield* Clock.currentTimeMillis);
|
|
180
|
+
if (used >= until)
|
|
181
|
+
return used;
|
|
182
|
+
yield* Queue.take(changed).pipe(Effect.timeoutOption(until - used));
|
|
183
|
+
}
|
|
184
|
+
});
|
|
185
|
+
/** Records the unsupervised time if it grew since the last record; logs a failure. */
|
|
186
|
+
const recordCounted = Effect.fn("AttemptGuard.recordUnsupervised")(function* () {
|
|
187
|
+
yield* Effect.annotateCurrentSpan({ attemptId });
|
|
188
|
+
const used = usedAt(yield* Clock.currentTimeMillis);
|
|
189
|
+
if (used <= recorded) {
|
|
190
|
+
yield* Effect.logDebug("Attempt unsupervised time has not grown since its last record", {
|
|
191
|
+
attemptId,
|
|
192
|
+
unsupervisedMillis: used,
|
|
193
|
+
});
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
yield* record(Duration.millis(used)).pipe(Effect.tap(() => Effect.sync(() => {
|
|
197
|
+
recorded = Math.max(recorded, used);
|
|
198
|
+
})), Effect.tapError((error) => Effect.logWarning("Could not record the Attempt's unsupervised time", {
|
|
199
|
+
attemptId,
|
|
200
|
+
unsupervisedMillis: used,
|
|
201
|
+
errorTag: error._tag,
|
|
202
|
+
})), Effect.ignore);
|
|
203
|
+
});
|
|
204
|
+
// Bounded by LAST_RECORD_GRACE; on timeout, the time since the previous record is lost.
|
|
205
|
+
const lastRecord = recordCounted().pipe(Effect.timeoutOption(LAST_RECORD_GRACE), Effect.flatMap(Option.match({
|
|
206
|
+
onSome: () => Effect.void,
|
|
207
|
+
onNone: () => Effect.logWarning("Recording the Attempt's unsupervised time exceeded its grace as its guard stopped", { attemptId, graceMillis: Duration.toMillis(LAST_RECORD_GRACE) }),
|
|
208
|
+
})));
|
|
209
|
+
const watch = Effect.gen(function* () {
|
|
210
|
+
yield* Effect.annotateCurrentSpan({ attemptId });
|
|
211
|
+
watching = true;
|
|
212
|
+
supervise(yield* Clock.currentTimeMillis);
|
|
213
|
+
if (!seed.warned.has("wall-clock")) {
|
|
214
|
+
const used = yield* unsupervised(wallClock.warnAt);
|
|
215
|
+
yield* warn("wall-clock", warning("wall-clock", Math.round(used / 6_000) / 10, wallClock.limit / 60_000));
|
|
216
|
+
}
|
|
217
|
+
yield* unsupervised(wallClock.limit);
|
|
218
|
+
yield* Effect.logWarning("Attempt reached its unsupervised wall-clock limit", {
|
|
219
|
+
attemptId,
|
|
220
|
+
maxAttemptMinutes: wallClock.limit / 60_000,
|
|
221
|
+
});
|
|
222
|
+
return yield* new RunawayFailure({ ceiling: "wall-clock" });
|
|
223
|
+
}).pipe(Effect.raceFirst(Effect.forever(Effect.sleep(RECORD_INTERVAL).pipe(Effect.andThen(recordCounted())))), Effect.onInterrupt(() => lastRecord), Effect.withSpan("AttemptGuard.watch"));
|
|
224
|
+
return { observe, watch };
|
|
225
|
+
});
|
|
226
|
+
/**
|
|
227
|
+
* Arms the configured Attempt ceilings, each with one warning steer at `WARNING_FRACTION` of
|
|
228
|
+
* its limit. Holds pause the wall clock; tokens keep accumulating. Counts continue from `seed`,
|
|
229
|
+
* so a reattached Attempt trips at the same totals as without the restart. With no ceiling set,
|
|
230
|
+
* `sink` is `io` and `tripped` never completes.
|
|
231
|
+
*/
|
|
232
|
+
export const attemptGuard = (limits, io, seed) => {
|
|
233
|
+
const wallClock = Option.map(limits.maxAttemptMinutes, (minutes) => ceiling(minutes * 60_000));
|
|
234
|
+
const tokens = Option.map(limits.maxAttemptTokens, ceiling);
|
|
235
|
+
if (Option.isNone(wallClock) && Option.isNone(tokens)) {
|
|
236
|
+
return Effect.succeed({ sink: io, tripped: Effect.never });
|
|
237
|
+
}
|
|
238
|
+
return Effect.gen(function* () {
|
|
239
|
+
const warnings = yield* Queue.unbounded();
|
|
240
|
+
const warn = (ceiling, message) => Effect.logInfo("Warning the Attempt before its ceiling", {
|
|
241
|
+
attemptId: limits.attemptId,
|
|
242
|
+
ceiling,
|
|
243
|
+
}).pipe(Effect.andThen(Queue.offer(warnings, { ceiling, message })), Effect.asVoid);
|
|
244
|
+
const deliver = Effect.fn("AttemptGuard.deliverWarning")(function* (ceiling, message) {
|
|
245
|
+
yield* Effect.annotateCurrentSpan({ attemptId: limits.attemptId, ceiling });
|
|
246
|
+
yield* limits.warn(message).pipe(Effect.tap(() => Effect.logInfo("Delivered the Attempt's ceiling warning", {
|
|
247
|
+
attemptId: limits.attemptId,
|
|
248
|
+
ceiling,
|
|
249
|
+
})), Effect.tapError((error) => Effect.logWarning("Attempt ceiling warning was not delivered", {
|
|
250
|
+
attemptId: limits.attemptId,
|
|
251
|
+
ceiling,
|
|
252
|
+
errorTag: error._tag,
|
|
253
|
+
})), Effect.ignore);
|
|
254
|
+
});
|
|
255
|
+
const meter = Option.map(tokens, (tokens) => tokenWatcher(limits.attemptId, tokens, warn, seed));
|
|
256
|
+
const clock = yield* Effect.transposeOption(Option.map(wallClock, (wallClock) => wallClockWatcher(limits.attemptId, wallClock, warn, limits.recordUnsupervised, seed)));
|
|
257
|
+
const sink = {
|
|
258
|
+
append: Effect.fn("AttemptGuard.append")(function* (direction, envelope) {
|
|
259
|
+
yield* Effect.annotateCurrentSpan({ attemptId: limits.attemptId });
|
|
260
|
+
yield* io.append(direction, envelope);
|
|
261
|
+
if (Option.isSome(meter))
|
|
262
|
+
yield* meter.value.observe(envelope);
|
|
263
|
+
if (Option.isSome(clock))
|
|
264
|
+
yield* clock.value.observe(envelope);
|
|
265
|
+
}),
|
|
266
|
+
salvage: io.salvage,
|
|
267
|
+
comments: io.comments,
|
|
268
|
+
windows: io.windows,
|
|
269
|
+
transcript: io.transcript,
|
|
270
|
+
};
|
|
271
|
+
const restoredTokens = Option.match(meter, {
|
|
272
|
+
onNone: () => Effect.never,
|
|
273
|
+
onSome: ({ resume }) => Effect.andThen(resume, Effect.never),
|
|
274
|
+
});
|
|
275
|
+
const wallClockTrip = Option.match(clock, {
|
|
276
|
+
onNone: () => Effect.never,
|
|
277
|
+
onSome: ({ watch }) => watch,
|
|
278
|
+
});
|
|
279
|
+
// Delivers warnings in a separate loop so a delivery waiting for the parent's channel doesn't
|
|
280
|
+
// delay a trip (#178).
|
|
281
|
+
const delivery = Effect.forever(Effect.flatMap(Queue.take(warnings), ({ ceiling, message }) => deliver(ceiling, message)));
|
|
282
|
+
return {
|
|
283
|
+
sink,
|
|
284
|
+
tripped: Effect.raceFirst(Effect.raceFirst(restoredTokens, wallClockTrip), delivery),
|
|
285
|
+
};
|
|
286
|
+
});
|
|
287
|
+
};
|
|
288
|
+
//# sourceMappingURL=guard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"guard.js","sourceRoot":"","sources":["../src/guard.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,27 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { ChildHost } from "@usine/agents/child-host";
|
|
2
|
+
import type { BrainSpec } from "@usine/core/agent/brain";
|
|
3
|
+
import type { HarnessReadiness } from "@usine/core/agent/capability";
|
|
4
|
+
import type { WorkerName } from "@usine/core/worker";
|
|
2
5
|
import { Effect } from "effect";
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
+
import { ChildProcessSpawner } from "effect/unstable/process";
|
|
7
|
+
import { ExecutorOperationError, WorkerCapabilityError } from "./executor.ts";
|
|
8
|
+
/**
|
|
9
|
+
* A function that reports one brain's readiness on a Worker. Only a readiness report indicates a
|
|
10
|
+
* capability gap; transport failures and timeouts are retryable `ExecutorOperationError`s.
|
|
11
|
+
*/
|
|
12
|
+
export type HarnessProbe = (brain: BrainSpec) => Effect.Effect<HarnessReadiness, ExecutorOperationError | WorkerCapabilityError>;
|
|
13
|
+
/**
|
|
14
|
+
* Probes each distinct brain and fails with a capability error if a harness is unavailable. A
|
|
15
|
+
* Claude probe holds `worker`'s lock in `logins`, so two preparations on one Worker never
|
|
16
|
+
* refresh the Claude login concurrently or while a Claude child starts (#453).
|
|
17
|
+
*/
|
|
18
|
+
export declare const verifyHarnessReadiness: (worker: string & import("effect/Brand").Brand<"WorkerName">, brains: readonly BrainSpec[], probe: HarnessProbe, logins: {
|
|
19
|
+
readonly withLock: (worker: WorkerName) => <A, E, R>(effect: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R>;
|
|
20
|
+
}) => Effect.Effect<undefined, import("./executor.ts").CredentialUnavailableError | ExecutorOperationError | WorkerCapabilityError, never>;
|
|
21
|
+
/**
|
|
22
|
+
* Returns a probe that checks one brain where `host` runs children, with `environment` as the
|
|
23
|
+
* child's environment (ADR 0011). A timeout or unreachable host is a retryable infrastructure
|
|
24
|
+
* error.
|
|
25
|
+
*/
|
|
26
|
+
export declare const agentsHarnessProbe: (spawner: ChildProcessSpawner.ChildProcessSpawner["Service"], host: ChildHost, environment: Readonly<Record<string, string>>) => HarnessProbe;
|
|
6
27
|
//# sourceMappingURL=harness-preflight.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"harness-preflight.d.ts","sourceRoot":"","sources":["../src/harness-preflight.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"harness-preflight.d.ts","sourceRoot":"","sources":["../src/harness-preflight.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAG1D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AACrE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAgB,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,EAAuB,sBAAsB,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAEnG;;;GAGG;AACH,MAAM,MAAM,YAAY,GAAG,CACzB,KAAK,EAAE,SAAS,KACb,MAAM,CAAC,MAAM,CAAC,gBAAgB,EAAE,sBAAsB,GAAG,qBAAqB,CAAC,CAAC;AAErF;;;;GAIG;AACH,eAAO,MAAM,sBAAsB;;0IA8BZ,CAAC;AAExB;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,YAElB,mBAAmB,CAAC,mBAAmB,CAAC,SAAS,CAAC,QACrD,SAAS,eACF,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,KAC5C,YAcA,CAAC"}
|
|
@@ -1,36 +1,22 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { logPreflightFailure, ExecutorOperationError, WorkerCapabilityError
|
|
5
|
-
/**
|
|
6
|
-
|
|
1
|
+
import { preflight } from "@usine/agents/preflight";
|
|
2
|
+
import { Array as Arr, Effect } from "effect";
|
|
3
|
+
import { ChildProcessSpawner } from "effect/unstable/process";
|
|
4
|
+
import { logPreflightFailure, ExecutorOperationError, WorkerCapabilityError } from "./executor.js";
|
|
5
|
+
/**
|
|
6
|
+
* Probes each distinct brain and fails with a capability error if a harness is unavailable. A
|
|
7
|
+
* Claude probe holds `worker`'s lock in `logins`, so two preparations on one Worker never
|
|
8
|
+
* refresh the Claude login concurrently or while a Claude child starts (#453).
|
|
9
|
+
*/
|
|
10
|
+
export const verifyHarnessReadiness = Effect.fn("Executor.verifyHarnessReadiness")(function* (worker, brains, probe, logins) {
|
|
7
11
|
yield* Effect.annotateCurrentSpan({ worker });
|
|
8
12
|
const distinct = Arr.dedupe(brains);
|
|
9
13
|
for (const brain of distinct) {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
const response = yield* execute(runHost.command, [
|
|
13
|
-
...runHost.args,
|
|
14
|
-
"--preflight",
|
|
15
|
-
Schema.encodeSync(Schema.fromJsonString(BrainSpec))(brain),
|
|
16
|
-
]).pipe(Effect.timeout("75 seconds"), Effect.catchTag("TimeoutError", (cause) => new ExecutorOperationError({
|
|
17
|
-
operation: "preflight",
|
|
18
|
-
message: `Worker ${worker} did not finish probing ${brain.harness} readiness`,
|
|
19
|
-
cause,
|
|
20
|
-
})));
|
|
21
|
-
const result = yield* Schema.decodeUnknownEffect(Schema.fromJsonString(HarnessReadiness))(response, { onExcessProperty: "error" }).pipe(Effect.mapError(() => new WorkerCapabilityError({
|
|
22
|
-
worker,
|
|
23
|
-
capability: "run-host",
|
|
24
|
-
message: `Worker ${worker} returned an invalid harness preflight response; update its run host`,
|
|
25
|
-
cause: new Error("invalid harness readiness response"),
|
|
26
|
-
})));
|
|
27
|
-
if (result.harness !== brain.harness)
|
|
28
|
-
return yield* new WorkerCapabilityError({
|
|
14
|
+
const result = yield* brain.harness === "claude"
|
|
15
|
+
? Effect.logDebug("Checking Claude under the Worker's Claude login lock", {
|
|
29
16
|
worker,
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
});
|
|
17
|
+
model: brain.model,
|
|
18
|
+
}).pipe(Effect.andThen(logins.withLock(worker)(probe(brain))))
|
|
19
|
+
: probe(brain);
|
|
34
20
|
if (result._tag === "HarnessUnavailableError")
|
|
35
21
|
return yield* new WorkerCapabilityError({
|
|
36
22
|
worker,
|
|
@@ -47,4 +33,14 @@ export const verifyHarnesses = Effect.fn("Executor.verifyHarnesses")(function* (
|
|
|
47
33
|
if (distinct.length === 0)
|
|
48
34
|
yield* Effect.logDebug("No rostered harnesses to preflight", { worker });
|
|
49
35
|
}, logPreflightFailure);
|
|
36
|
+
/**
|
|
37
|
+
* Returns a probe that checks one brain where `host` runs children, with `environment` as the
|
|
38
|
+
* child's environment (ADR 0011). A timeout or unreachable host is a retryable infrastructure
|
|
39
|
+
* error.
|
|
40
|
+
*/
|
|
41
|
+
export const agentsHarnessProbe = (spawner, host, environment) => (brain) => preflight(brain, host, environment).pipe(Effect.map((ready) => ready), Effect.catchTag("HarnessUnavailableError", (unavailable) => Effect.succeed(unavailable)), Effect.mapError((cause) => new ExecutorOperationError({
|
|
42
|
+
operation: "preflight",
|
|
43
|
+
message: cause.message,
|
|
44
|
+
cause,
|
|
45
|
+
})), Effect.provideService(ChildProcessSpawner.ChildProcessSpawner, spawner));
|
|
50
46
|
//# sourceMappingURL=harness-preflight.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"harness-preflight.js","sourceRoot":"","sources":["../src/harness-preflight.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"harness-preflight.js","sourceRoot":"","sources":["../src/harness-preflight.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAKpD,OAAO,EAAE,KAAK,IAAI,GAAG,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,EAAE,mBAAmB,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAUnG;;;;GAIG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,MAAM,CAAC,EAAE,CAAC,iCAAiC,CAAC,CAAC,QAAQ,CAAC,EAC1F,MAAkB,EAClB,MAAgC,EAChC,KAAmB,EACnB,MAAkC;IAElC,KAAK,CAAC,CAAC,MAAM,CAAC,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC;IAC9C,MAAM,QAAQ,GAAG,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACpC,KAAK,MAAM,KAAK,IAAI,QAAQ,EAAE,CAAC;QAC7B,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,KAAK,CAAC,OAAO,KAAK,QAAQ;YAC9C,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,sDAAsD,EAAE;gBACtE,MAAM;gBACN,KAAK,EAAE,KAAK,CAAC,KAAK;aACnB,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YAChE,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QACjB,IAAI,MAAM,CAAC,IAAI,KAAK,yBAAyB;YAC3C,OAAO,KAAK,CAAC,CAAC,IAAI,qBAAqB,CAAC;gBACtC,MAAM;gBACN,UAAU,EAAE,MAAM,CAAC,UAAU,KAAK,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,WAAW;gBACzE,OAAO,EAAE,MAAM,CAAC,OAAO;gBACvB,KAAK,EAAE,MAAM;aACd,CAAC,CAAC;QACL,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,mCAAmC,EAAE;YACzD,MAAM;YACN,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,KAAK,EAAE,KAAK,CAAC,KAAK;SACnB,CAAC,CAAC;IACL,CAAC;IACD,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QACvB,KAAK,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,oCAAoC,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;AAC7E,CAAC,EAAE,mBAAmB,CAAC,CAAC;AAExB;;;;GAIG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAC7B,CACE,OAA2D,EAC3D,IAAe,EACf,WAA6C,EAC/B,EAAE,CAClB,CAAC,KAAK,EAAE,EAAE,CACR,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,WAAW,CAAC,CAAC,IAAI,CACtC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAoB,EAAE,CAAC,KAAK,CAAC,EAC9C,MAAM,CAAC,QAAQ,CAAC,yBAAyB,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,EACxF,MAAM,CAAC,QAAQ,CACb,CAAC,KAAK,EAAE,EAAE,CACR,IAAI,sBAAsB,CAAC;IACzB,SAAS,EAAE,WAAW;IACtB,OAAO,EAAE,KAAK,CAAC,OAAO;IACtB,KAAK;CACN,CAAC,CACL,EACD,MAAM,CAAC,cAAc,CAAC,mBAAmB,CAAC,mBAAmB,EAAE,OAAO,CAAC,CACxE,CAAC"}
|
package/dist/keyed-lock.d.ts
CHANGED
|
@@ -3,9 +3,8 @@ export interface KeyedLock<in K> {
|
|
|
3
3
|
readonly withLock: (key: K) => <A, E, R>(effect: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R>;
|
|
4
4
|
}
|
|
5
5
|
/**
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* `make({ permits: 1 })` serializes every key behind a single global permit.
|
|
6
|
+
* Returns one mutex per key. `PartitionedSemaphore` doesn't provide this: its `permits` is one
|
|
7
|
+
* shared pool, so `make({ permits: 1 })` serializes every key.
|
|
9
8
|
*/
|
|
10
9
|
export declare const keyedLockFor: <K>() => Effect.Effect<KeyedLock<K>>;
|
|
11
10
|
//# sourceMappingURL=keyed-lock.d.ts.map
|
package/dist/keyed-lock.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"keyed-lock.d.ts","sourceRoot":"","sources":["../src/keyed-lock.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAkB,MAAM,QAAQ,CAAC;AAEhD,MAAM,WAAW,SAAS,CAAC,EAAE,CAAC,CAAC;IAC7B,QAAQ,CAAC,QAAQ,EAAE,CACjB,GAAG,EAAE,CAAC,KACH,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,KAAK,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;CAC1E;AAED
|
|
1
|
+
{"version":3,"file":"keyed-lock.d.ts","sourceRoot":"","sources":["../src/keyed-lock.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAkB,MAAM,QAAQ,CAAC;AAEhD,MAAM,WAAW,SAAS,CAAC,EAAE,CAAC,CAAC;IAC7B,QAAQ,CAAC,QAAQ,EAAE,CACjB,GAAG,EAAE,CAAC,KACH,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,KAAK,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;CAC1E;AAED;;;GAGG;AACH,eAAO,MAAM,YAAY,GAAI,CAAC,OAAK,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAcxD,CAAC"}
|
package/dist/keyed-lock.js
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { Effect, Ref, Semaphore } from "effect";
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* `make({ permits: 1 })` serializes every key behind a single global permit.
|
|
3
|
+
* Returns one mutex per key. `PartitionedSemaphore` doesn't provide this: its `permits` is one
|
|
4
|
+
* shared pool, so `make({ permits: 1 })` serializes every key.
|
|
6
5
|
*/
|
|
7
6
|
export const keyedLockFor = () => Effect.map(Ref.make(new Map()), (locks) => ({
|
|
8
7
|
withLock: (key) => {
|
package/dist/keyed-lock.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"keyed-lock.js","sourceRoot":"","sources":["../src/keyed-lock.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AAQhD
|
|
1
|
+
{"version":3,"file":"keyed-lock.js","sourceRoot":"","sources":["../src/keyed-lock.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AAQhD;;;GAGG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,GAAmC,EAAE,CAC/D,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,GAAG,EAA0B,CAAC,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IAClE,QAAQ,EAAE,CAAC,GAAM,EAAE,EAAE;QACnB,MAAM,SAAS,GAAG,GAAG,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,OAAO,EAAE,EAAE;YAC9C,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YAClC,IAAI,QAAQ,KAAK,SAAS;gBAAE,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAU,CAAC;YAChE,MAAM,OAAO,GAAG,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;YACxC,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC;YAC9B,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;YACvB,OAAO,CAAC,OAAO,EAAE,IAAI,CAAU,CAAC;QAClC,CAAC,CAAC,CAAC;QACH,OAAO,CAAU,MAA8B,EAA0B,EAAE,CACzE,MAAM,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,SAAS,CAAC,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC;IAC5E,CAAC;CACF,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { WorkerName } from "@usine/core/worker";
|
|
2
|
+
import { Effect } from "effect";
|
|
3
|
+
/**
|
|
4
|
+
* Caches `list` per Worker for the life of one executor; concurrent callers share one listing.
|
|
5
|
+
* Failures are cached too, so an unreachable Worker is listed once and its checkouts stay until
|
|
6
|
+
* the next start.
|
|
7
|
+
*/
|
|
8
|
+
export declare const listedOncePerWorker: <A, E>(list: (worker: WorkerName) => Effect.Effect<A, E>) => Effect.Effect<(worker: WorkerName) => Effect.Effect<A, E, never>, never, never>;
|
|
9
|
+
//# sourceMappingURL=leftovers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"leftovers.d.ts","sourceRoot":"","sources":["../src/leftovers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAS,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEvC;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,GAAwD,CAAC,EAAE,CAAC,iBAC3E,UAAU,KAAK,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,4BAcjC,UAAU,8CAC1B,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Cache, Effect } from "effect";
|
|
2
|
+
/**
|
|
3
|
+
* Caches `list` per Worker for the life of one executor; concurrent callers share one listing.
|
|
4
|
+
* Failures are cached too, so an unreachable Worker is listed once and its checkouts stay until
|
|
5
|
+
* the next start.
|
|
6
|
+
*/
|
|
7
|
+
export const listedOncePerWorker = Effect.fn("Executor.listedOncePerWorker")(function* (list) {
|
|
8
|
+
const listed = yield* Cache.make({
|
|
9
|
+
capacity: Number.POSITIVE_INFINITY,
|
|
10
|
+
lookup: (worker) => list(worker).pipe(Effect.tapError((error) => Effect.logWarning("Could not list leftover checkouts; this Worker is not reconciled until the next start", { worker, message: String(error) }))),
|
|
11
|
+
});
|
|
12
|
+
return (worker) => Cache.get(listed, worker);
|
|
13
|
+
});
|
|
14
|
+
//# sourceMappingURL=leftovers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"leftovers.js","sourceRoot":"","sources":["../src/leftovers.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEvC;;;;GAIG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,MAAM,CAAC,EAAE,CAAC,8BAA8B,CAAC,CAAC,QAAQ,CAAC,EACpF,IAAiD;IAEjD,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC;QAC/B,QAAQ,EAAE,MAAM,CAAC,iBAAiB;QAClC,MAAM,EAAE,CAAC,MAAkB,EAAE,EAAE,CAC7B,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,CACf,MAAM,CAAC,QAAQ,CAAC,CAAC,KAAK,EAAE,EAAE,CACxB,MAAM,CAAC,UAAU,CACf,uFAAuF,EACvF,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,CACnC,CACF,CACF;KACJ,CAAC,CAAC;IACH,OAAO,CAAC,MAAkB,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAC3D,CAAC,CAAC,CAAC"}
|