@usine/orchestrator 0.0.0 → 0.1.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/LICENSE +21 -0
- package/README.md +126 -1
- package/dist/board/projection.d.ts +8 -0
- package/dist/board/projection.d.ts.map +1 -0
- package/dist/board/projection.js +151 -0
- package/dist/board/projection.js.map +1 -0
- package/dist/credentials.d.ts +12 -0
- package/dist/credentials.d.ts.map +1 -0
- package/dist/credentials.js +62 -0
- package/dist/credentials.js.map +1 -0
- package/dist/exe-dev.d.ts +7 -0
- package/dist/exe-dev.d.ts.map +1 -0
- package/dist/exe-dev.js +16 -0
- package/dist/exe-dev.js.map +1 -0
- package/dist/idle-triggers.d.ts +6 -0
- package/dist/idle-triggers.d.ts.map +1 -0
- package/dist/idle-triggers.js +29 -0
- package/dist/idle-triggers.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +11 -0
- package/dist/index.js.map +1 -0
- package/dist/local.d.ts +20 -0
- package/dist/local.d.ts.map +1 -0
- package/dist/local.js +46 -0
- package/dist/local.js.map +1 -0
- package/dist/operator/model.d.ts +280 -0
- package/dist/operator/model.d.ts.map +1 -0
- package/dist/operator/model.js +242 -0
- package/dist/operator/model.js.map +1 -0
- package/dist/operator/projection.d.ts +17 -0
- package/dist/operator/projection.d.ts.map +1 -0
- package/dist/operator/projection.js +130 -0
- package/dist/operator/projection.js.map +1 -0
- package/dist/operator/service.d.ts +36 -0
- package/dist/operator/service.d.ts.map +1 -0
- package/dist/operator/service.js +248 -0
- package/dist/operator/service.js.map +1 -0
- package/dist/orchestrator.d.ts +13 -0
- package/dist/orchestrator.d.ts.map +1 -0
- package/dist/orchestrator.js +14 -0
- package/dist/orchestrator.js.map +1 -0
- package/dist/polling-triggers.d.ts +40 -0
- package/dist/polling-triggers.d.ts.map +1 -0
- package/dist/polling-triggers.js +394 -0
- package/dist/polling-triggers.js.map +1 -0
- package/dist/schedule-triggers.d.ts +65 -0
- package/dist/schedule-triggers.d.ts.map +1 -0
- package/dist/schedule-triggers.js +391 -0
- package/dist/schedule-triggers.js.map +1 -0
- package/dist/scheduler.d.ts +15 -0
- package/dist/scheduler.d.ts.map +1 -0
- package/dist/scheduler.js +122 -0
- package/dist/scheduler.js.map +1 -0
- package/dist/trigger-submission.d.ts +60 -0
- package/dist/trigger-submission.d.ts.map +1 -0
- package/dist/trigger-submission.js +105 -0
- package/dist/trigger-submission.js.map +1 -0
- package/package.json +61 -4
|
@@ -0,0 +1,391 @@
|
|
|
1
|
+
import { ConfigParser, environmentFor, matchesSelector, repositoryContext, } from "@usine/config";
|
|
2
|
+
import { Agent, AttemptChannel, Event, Item, Loop, Repository } from "@usine/core";
|
|
3
|
+
import { LoopControl, RunEngine, SubmissionResult, } from "@usine/engine";
|
|
4
|
+
import { ExpressionEngine } from "@usine/expression";
|
|
5
|
+
import { Clock, Context, Cron, DateTime, Duration, Effect, Layer, Option, Ref, Result, Schema, } from "effect";
|
|
6
|
+
import { configFileErrorLogFields, resolveTriggerLoop, submissionLogFields, triggerSubmission, } from "./trigger-submission.js";
|
|
7
|
+
/** Fanout submits to local SQLite only — kept small so write transactions don't pile up. */
|
|
8
|
+
const FANOUT_CONCURRENCY = 4;
|
|
9
|
+
/** Wake cadence when no schedule can name its next boundary (none exist, or cron math is down). */
|
|
10
|
+
const IDLE_WAKE_MILLIS = 60_000;
|
|
11
|
+
const scheduleFailureLogFields = (error) => {
|
|
12
|
+
const common = { errorTag: error._tag, message: error.message };
|
|
13
|
+
if (error._tag === "ConfigFileError") {
|
|
14
|
+
return { ...common, ...configFileErrorLogFields(error) };
|
|
15
|
+
}
|
|
16
|
+
if (error._tag === "ExpressionCheckError" || error._tag === "ExpressionEvaluationError") {
|
|
17
|
+
return { ...common, expression: error.source };
|
|
18
|
+
}
|
|
19
|
+
return common;
|
|
20
|
+
};
|
|
21
|
+
/** One schedule loop whose authored Agent disappeared from the loaded roster. */
|
|
22
|
+
export class ScheduleAgentFailure extends Schema.TaggedClass("@usine/orchestrator/ScheduleAgentFailure")("ScheduleAgentFailure", {
|
|
23
|
+
loop: Loop.LoopName,
|
|
24
|
+
agent: Agent.Name,
|
|
25
|
+
message: Schema.String,
|
|
26
|
+
}) {
|
|
27
|
+
}
|
|
28
|
+
/** One selected repository whose scheduled Tick could not be evaluated or submitted. */
|
|
29
|
+
export class ScheduleTickFailure extends Schema.TaggedClass("@usine/orchestrator/ScheduleTickFailure")("ScheduleTickFailure", {
|
|
30
|
+
loop: Loop.LoopName,
|
|
31
|
+
repository: Repository.Name,
|
|
32
|
+
scheduledAt: Schema.DateTimeUtc,
|
|
33
|
+
errorTag: Schema.NonEmptyString,
|
|
34
|
+
message: Schema.String,
|
|
35
|
+
}) {
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* One schedule whose cron boundaries could not be computed at this instant —
|
|
39
|
+
* effect's Cron.prev/next can fail inside a DST spring-forward gap even for a
|
|
40
|
+
* cron that parsed cleanly. The schedule retries next cycle; siblings run.
|
|
41
|
+
*/
|
|
42
|
+
export class ScheduleCronFailure extends Schema.TaggedClass("@usine/orchestrator/ScheduleCronFailure")("ScheduleCronFailure", {
|
|
43
|
+
loop: Loop.LoopName,
|
|
44
|
+
cron: Schema.String,
|
|
45
|
+
tz: Schema.String,
|
|
46
|
+
message: Schema.String,
|
|
47
|
+
}) {
|
|
48
|
+
}
|
|
49
|
+
export const ScheduleFailure = Schema.Union([
|
|
50
|
+
ScheduleAgentFailure,
|
|
51
|
+
ScheduleCronFailure,
|
|
52
|
+
ScheduleTickFailure,
|
|
53
|
+
]);
|
|
54
|
+
/** Observable result of evaluating every schedule loop at one clock instant. */
|
|
55
|
+
export class ScheduleCycle extends Schema.Class("@usine/orchestrator/ScheduleCycle")({
|
|
56
|
+
loops: Schema.Int.check(Schema.isGreaterThanOrEqualTo(0)),
|
|
57
|
+
fanout: Schema.Int.check(Schema.isGreaterThanOrEqualTo(0)),
|
|
58
|
+
submissions: Schema.Array(SubmissionResult),
|
|
59
|
+
skipped: Schema.Int.check(Schema.isGreaterThanOrEqualTo(0)),
|
|
60
|
+
alreadyFired: Schema.Int.check(Schema.isGreaterThanOrEqualTo(0)),
|
|
61
|
+
failures: Schema.Array(ScheduleFailure),
|
|
62
|
+
nextTickAt: Schema.Option(Schema.DateTimeUtc),
|
|
63
|
+
}) {
|
|
64
|
+
}
|
|
65
|
+
const watchedSchedules = (instance) => instance.loops.flatMap((loop) => {
|
|
66
|
+
const trigger = loop.trigger;
|
|
67
|
+
if (trigger.on !== "schedule")
|
|
68
|
+
return [];
|
|
69
|
+
return [
|
|
70
|
+
{
|
|
71
|
+
loop,
|
|
72
|
+
repositories: instance.config.repos.filter((repository) => matchesSelector(loop.selector, repository)),
|
|
73
|
+
trigger,
|
|
74
|
+
},
|
|
75
|
+
];
|
|
76
|
+
});
|
|
77
|
+
/**
|
|
78
|
+
* Inclusive latest occurrence: Cron.prev itself is strict at an exact match.
|
|
79
|
+
* Across a DST fall-back the same local time maps to two UTC instants and both
|
|
80
|
+
* are legal boundaries — the payload's zone-local time makes the pair
|
|
81
|
+
* explicable in logs, and the permanent dedup ledger keeps each a single fact.
|
|
82
|
+
*/
|
|
83
|
+
const latestScheduledAt = (cron, now) => {
|
|
84
|
+
const minuteBoundary = DateTime.toDateUtc(now);
|
|
85
|
+
minuteBoundary.setUTCSeconds(0, 0);
|
|
86
|
+
return DateTime.fromDateUnsafe(Cron.match(cron, minuteBoundary) ? minuteBoundary : Cron.prev(cron, minuteBoundary));
|
|
87
|
+
};
|
|
88
|
+
const nextScheduledAt = (cron, now) => DateTime.fromDateUnsafe(Cron.next(cron, DateTime.toDateUtc(now)));
|
|
89
|
+
const localTime = (scheduledAt, tz) => Option.match(DateTime.setZoneNamed(scheduledAt, tz), {
|
|
90
|
+
onNone: () => DateTime.formatIso(scheduledAt),
|
|
91
|
+
onSome: DateTime.formatIsoZoned,
|
|
92
|
+
});
|
|
93
|
+
const earliest = (values) => {
|
|
94
|
+
if (values.length === 0)
|
|
95
|
+
return Option.none();
|
|
96
|
+
return DateTime.make(Math.min(...values.map(DateTime.toEpochMillis)));
|
|
97
|
+
};
|
|
98
|
+
const itemKey = (repository) => Item.ItemKey.make(JSON.stringify(["github", Repository.canonical(repository.name)]));
|
|
99
|
+
const eventKey = (loop, repository, scheduledAt) => Event.DedupKey.make(JSON.stringify([
|
|
100
|
+
loop.name,
|
|
101
|
+
Repository.canonical(repository.name),
|
|
102
|
+
DateTime.formatIso(scheduledAt),
|
|
103
|
+
]));
|
|
104
|
+
const tickPayload = (due) => ({
|
|
105
|
+
tick: {
|
|
106
|
+
scheduledAt: DateTime.formatIso(due.scheduledAt),
|
|
107
|
+
scheduledAtLocal: due.scheduledAtLocal,
|
|
108
|
+
cron: due.trigger.cron,
|
|
109
|
+
tz: due.trigger.tz,
|
|
110
|
+
},
|
|
111
|
+
});
|
|
112
|
+
/** Clock-driven schedule → per-repository Event composition. */
|
|
113
|
+
export class ScheduleTriggers extends Context.Service()("@usine/orchestrator/ScheduleTriggers") {
|
|
114
|
+
static layer = Layer.effect(ScheduleTriggers, Effect.gen(function* () {
|
|
115
|
+
const config = yield* ConfigParser;
|
|
116
|
+
const expressions = yield* ExpressionEngine;
|
|
117
|
+
const runs = yield* RunEngine;
|
|
118
|
+
const loops = yield* LoopControl;
|
|
119
|
+
const latestCycle = yield* Ref.make(Option.none());
|
|
120
|
+
// Efficiency-only fired-tick memory: an empty map after a restart is
|
|
121
|
+
// exactly ADR 0007's "fire the latest missed tick"; the permanent dedup
|
|
122
|
+
// ledger stays the correctness guarantee.
|
|
123
|
+
const lastFired = yield* Ref.make(new Map());
|
|
124
|
+
// Cron sources are immutable once parsed at the config boundary; parsing
|
|
125
|
+
// again per cycle is waste. parseUnsafe trusts that boundary validation.
|
|
126
|
+
const parsedCrons = new WeakMap();
|
|
127
|
+
const cronFor = (trigger) => {
|
|
128
|
+
const cached = parsedCrons.get(trigger);
|
|
129
|
+
if (cached !== undefined)
|
|
130
|
+
return cached;
|
|
131
|
+
const parsed = Cron.parseUnsafe(trigger.cron, trigger.tz);
|
|
132
|
+
parsedCrons.set(trigger, parsed);
|
|
133
|
+
return parsed;
|
|
134
|
+
};
|
|
135
|
+
const submitTick = Effect.fn("ScheduleTriggers.submitTick")(function* (due, receivedAt) {
|
|
136
|
+
yield* Effect.annotateCurrentSpan({
|
|
137
|
+
loop: due.loop.name,
|
|
138
|
+
repository: due.repository.name,
|
|
139
|
+
agent: due.agent.name,
|
|
140
|
+
scheduledAt: DateTime.formatIso(due.scheduledAt),
|
|
141
|
+
});
|
|
142
|
+
const payload = tickPayload(due);
|
|
143
|
+
const context = { repo: repositoryContext(due.repository), item: payload };
|
|
144
|
+
const matches = yield* expressions.evaluateBoolean(due.trigger.if, environmentFor("schedule"), context);
|
|
145
|
+
if (!matches) {
|
|
146
|
+
yield* Effect.logDebug("Scheduled Tick did not match its expression", {
|
|
147
|
+
loop: due.loop.name,
|
|
148
|
+
repository: due.repository.name,
|
|
149
|
+
agent: due.agent.name,
|
|
150
|
+
scheduledAt: DateTime.formatIso(due.scheduledAt),
|
|
151
|
+
});
|
|
152
|
+
return Option.none();
|
|
153
|
+
}
|
|
154
|
+
const dedupKey = eventKey(due.loop, due.repository, due.scheduledAt);
|
|
155
|
+
const task = yield* config.renderPrompt(due.loop, context);
|
|
156
|
+
const submitted = yield* runs.submit(triggerSubmission({
|
|
157
|
+
agent: due.agent,
|
|
158
|
+
dedupKey,
|
|
159
|
+
itemKey: itemKey(due.repository),
|
|
160
|
+
loop: due.loop,
|
|
161
|
+
payload,
|
|
162
|
+
receivedAt,
|
|
163
|
+
repository: due.repository,
|
|
164
|
+
task: AttemptChannel.Task.make(task),
|
|
165
|
+
parentModel: due.parentModel,
|
|
166
|
+
}));
|
|
167
|
+
yield* Effect.logInfo("Submitted scheduled Tick", {
|
|
168
|
+
loop: due.loop.name,
|
|
169
|
+
repository: due.repository.name,
|
|
170
|
+
agent: due.agent.name,
|
|
171
|
+
scheduledAt: DateTime.formatIso(due.scheduledAt),
|
|
172
|
+
scheduledAtLocal: due.scheduledAtLocal,
|
|
173
|
+
result: submitted._tag,
|
|
174
|
+
...submissionLogFields(submitted),
|
|
175
|
+
});
|
|
176
|
+
return Option.some(submitted);
|
|
177
|
+
});
|
|
178
|
+
const tick = Effect.fn("ScheduleTriggers.tick")(function* (instance) {
|
|
179
|
+
const now = yield* DateTime.now;
|
|
180
|
+
const paused = new Set((yield* loops.states).filter((state) => state.paused).map((state) => state.loop));
|
|
181
|
+
for (const loop of instance.loops) {
|
|
182
|
+
if (loop.trigger.on === "schedule" && paused.has(loop.name)) {
|
|
183
|
+
yield* Effect.logDebug("Paused Loop skipped during schedule evaluation", {
|
|
184
|
+
loop: loop.name,
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
const schedules = watchedSchedules(instance).filter(({ loop }) => !paused.has(loop.name));
|
|
189
|
+
const fired = yield* Ref.get(lastFired);
|
|
190
|
+
const due = [];
|
|
191
|
+
const agentFailures = [];
|
|
192
|
+
const cronFailures = [];
|
|
193
|
+
const boundariesByLoop = new Map();
|
|
194
|
+
const nexts = [];
|
|
195
|
+
let alreadyFired = 0;
|
|
196
|
+
for (const schedule of schedules) {
|
|
197
|
+
if (schedule.repositories.length === 0) {
|
|
198
|
+
yield* Effect.logWarning("Schedule loop selected no repositories", {
|
|
199
|
+
loop: schedule.loop.name,
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
// Cron evaluation can throw inside a DST spring-forward gap even
|
|
203
|
+
// though the expression parsed cleanly; one schedule's bad instant
|
|
204
|
+
// must never take the stream down.
|
|
205
|
+
const computed = yield* Effect.try({
|
|
206
|
+
try: () => {
|
|
207
|
+
const cron = cronFor(schedule.trigger);
|
|
208
|
+
const latest = latestScheduledAt(cron, now);
|
|
209
|
+
return {
|
|
210
|
+
latest,
|
|
211
|
+
latestLocal: localTime(latest, schedule.trigger.tz),
|
|
212
|
+
next: nextScheduledAt(cron, now),
|
|
213
|
+
};
|
|
214
|
+
},
|
|
215
|
+
catch: (cause) => cause,
|
|
216
|
+
}).pipe(Effect.result);
|
|
217
|
+
if (Result.isFailure(computed)) {
|
|
218
|
+
yield* Effect.logError("Schedule cron boundaries could not be computed", {
|
|
219
|
+
loop: schedule.loop.name,
|
|
220
|
+
cron: schedule.trigger.cron,
|
|
221
|
+
tz: schedule.trigger.tz,
|
|
222
|
+
message: String(computed.failure),
|
|
223
|
+
});
|
|
224
|
+
cronFailures.push(new ScheduleCronFailure({
|
|
225
|
+
loop: schedule.loop.name,
|
|
226
|
+
cron: schedule.trigger.cron,
|
|
227
|
+
tz: schedule.trigger.tz,
|
|
228
|
+
message: String(computed.failure),
|
|
229
|
+
}));
|
|
230
|
+
continue;
|
|
231
|
+
}
|
|
232
|
+
const boundaries = computed.success;
|
|
233
|
+
nexts.push(boundaries.next);
|
|
234
|
+
const latestEpoch = DateTime.toEpochMillis(boundaries.latest);
|
|
235
|
+
const last = fired.get(schedule.loop.name);
|
|
236
|
+
if (last !== undefined && last >= latestEpoch) {
|
|
237
|
+
alreadyFired += 1;
|
|
238
|
+
yield* Effect.logDebug("Tick already fired", {
|
|
239
|
+
loop: schedule.loop.name,
|
|
240
|
+
scheduledAt: DateTime.formatIso(boundaries.latest),
|
|
241
|
+
});
|
|
242
|
+
continue;
|
|
243
|
+
}
|
|
244
|
+
const resolved = yield* Effect.result(resolveTriggerLoop(instance, schedule.loop));
|
|
245
|
+
if (Result.isFailure(resolved)) {
|
|
246
|
+
const error = resolved.failure;
|
|
247
|
+
yield* Effect.logError("Schedule loop could not resolve its Agent", {
|
|
248
|
+
loop: error.loop,
|
|
249
|
+
agent: error.agent,
|
|
250
|
+
errorTag: error._tag,
|
|
251
|
+
message: error.message,
|
|
252
|
+
});
|
|
253
|
+
agentFailures.push(new ScheduleAgentFailure({
|
|
254
|
+
loop: error.loop,
|
|
255
|
+
agent: error.agent,
|
|
256
|
+
message: error.message,
|
|
257
|
+
}));
|
|
258
|
+
continue;
|
|
259
|
+
}
|
|
260
|
+
if (schedule.repositories.length === 0)
|
|
261
|
+
continue;
|
|
262
|
+
boundariesByLoop.set(schedule.loop.name, latestEpoch);
|
|
263
|
+
yield* Effect.logInfo("Schedule tick due", {
|
|
264
|
+
loop: schedule.loop.name,
|
|
265
|
+
agent: resolved.success.agent.name,
|
|
266
|
+
cron: schedule.trigger.cron,
|
|
267
|
+
tz: schedule.trigger.tz,
|
|
268
|
+
scheduledAt: DateTime.formatIso(boundaries.latest),
|
|
269
|
+
scheduledAtLocal: boundaries.latestLocal,
|
|
270
|
+
repositories: schedule.repositories.length,
|
|
271
|
+
nextTickAt: DateTime.formatIso(boundaries.next),
|
|
272
|
+
});
|
|
273
|
+
for (const repository of schedule.repositories) {
|
|
274
|
+
due.push({
|
|
275
|
+
agent: resolved.success.agent,
|
|
276
|
+
loop: schedule.loop,
|
|
277
|
+
parentModel: resolved.success.parentModel,
|
|
278
|
+
repository,
|
|
279
|
+
scheduledAt: boundaries.latest,
|
|
280
|
+
scheduledAtLocal: boundaries.latestLocal,
|
|
281
|
+
trigger: schedule.trigger,
|
|
282
|
+
});
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
yield* Effect.annotateCurrentSpan({ schedules: schedules.length, fanout: due.length });
|
|
286
|
+
const settled = yield* Effect.forEach(due, (candidate) => Effect.result(submitTick(candidate, now)).pipe(Effect.map((result) => ({ candidate, result }))), { concurrency: FANOUT_CONCURRENCY });
|
|
287
|
+
const submissions = [];
|
|
288
|
+
const tickFailures = [];
|
|
289
|
+
const submittedLoops = new Set();
|
|
290
|
+
const failedLoops = new Set();
|
|
291
|
+
let skipped = 0;
|
|
292
|
+
for (const { candidate, result } of settled) {
|
|
293
|
+
if (Result.isSuccess(result)) {
|
|
294
|
+
if (Option.isSome(result.success)) {
|
|
295
|
+
submissions.push(result.success.value);
|
|
296
|
+
submittedLoops.add(candidate.loop.name);
|
|
297
|
+
}
|
|
298
|
+
else
|
|
299
|
+
skipped += 1;
|
|
300
|
+
continue;
|
|
301
|
+
}
|
|
302
|
+
const error = result.failure;
|
|
303
|
+
failedLoops.add(candidate.loop.name);
|
|
304
|
+
yield* Effect.logError("Scheduled Tick failed; sibling fanout was unaffected", {
|
|
305
|
+
loop: candidate.loop.name,
|
|
306
|
+
repository: candidate.repository.name,
|
|
307
|
+
agent: candidate.agent.name,
|
|
308
|
+
scheduledAt: DateTime.formatIso(candidate.scheduledAt),
|
|
309
|
+
...scheduleFailureLogFields(error),
|
|
310
|
+
});
|
|
311
|
+
tickFailures.push(new ScheduleTickFailure({
|
|
312
|
+
loop: candidate.loop.name,
|
|
313
|
+
repository: candidate.repository.name,
|
|
314
|
+
scheduledAt: candidate.scheduledAt,
|
|
315
|
+
errorTag: error._tag,
|
|
316
|
+
message: error.message,
|
|
317
|
+
}));
|
|
318
|
+
}
|
|
319
|
+
// Advance the fired-tick memory only for loops that submitted without
|
|
320
|
+
// a failure: an all-unmatched tick keeps re-evaluating (so a fixed
|
|
321
|
+
// `if:` still fires it), a failed loop retries every repository next
|
|
322
|
+
// cycle, and the dedup ledger absorbs the ones that already landed.
|
|
323
|
+
yield* Ref.update(lastFired, (current) => {
|
|
324
|
+
const next = new Map(current);
|
|
325
|
+
for (const [loop, latestEpoch] of boundariesByLoop) {
|
|
326
|
+
if (submittedLoops.has(loop) && !failedLoops.has(loop)) {
|
|
327
|
+
next.set(loop, latestEpoch);
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
return next;
|
|
331
|
+
});
|
|
332
|
+
const cycle = new ScheduleCycle({
|
|
333
|
+
loops: schedules.length,
|
|
334
|
+
fanout: due.length,
|
|
335
|
+
submissions,
|
|
336
|
+
skipped,
|
|
337
|
+
alreadyFired,
|
|
338
|
+
failures: [...agentFailures, ...cronFailures, ...tickFailures],
|
|
339
|
+
nextTickAt: earliest(nexts),
|
|
340
|
+
});
|
|
341
|
+
yield* Ref.set(latestCycle, Option.some(cycle));
|
|
342
|
+
return cycle;
|
|
343
|
+
});
|
|
344
|
+
// No Effect.fn here: `run` never returns, so a named wrapper would open
|
|
345
|
+
// a span that never closes. Each cycle's span lives on `tick`.
|
|
346
|
+
const run = (instance) => Effect.gen(function* () {
|
|
347
|
+
const result = yield* Effect.result(tick(instance));
|
|
348
|
+
if (Result.isFailure(result)) {
|
|
349
|
+
yield* Effect.logError("Schedule cycle could not read Loop runtime state; retrying", {
|
|
350
|
+
errorTag: result.failure._tag,
|
|
351
|
+
message: result.failure.message,
|
|
352
|
+
operation: result.failure.operation,
|
|
353
|
+
sleepMs: IDLE_WAKE_MILLIS,
|
|
354
|
+
});
|
|
355
|
+
yield* Effect.sleep(Duration.millis(IDLE_WAKE_MILLIS));
|
|
356
|
+
return;
|
|
357
|
+
}
|
|
358
|
+
const cycle = result.success;
|
|
359
|
+
const now = yield* Clock.currentTimeMillis;
|
|
360
|
+
const target = Option.match(cycle.nextTickAt, {
|
|
361
|
+
onNone: () => now + IDLE_WAKE_MILLIS,
|
|
362
|
+
onSome: DateTime.toEpochMillis,
|
|
363
|
+
});
|
|
364
|
+
const sleepMs = Math.min(IDLE_WAKE_MILLIS, Math.max(0, target - now));
|
|
365
|
+
const summary = {
|
|
366
|
+
loops: cycle.loops,
|
|
367
|
+
fanout: cycle.fanout,
|
|
368
|
+
submissions: cycle.submissions.length,
|
|
369
|
+
skipped: cycle.skipped,
|
|
370
|
+
alreadyFired: cycle.alreadyFired,
|
|
371
|
+
failures: cycle.failures.length,
|
|
372
|
+
nextTickAt: Option.match(cycle.nextTickAt, {
|
|
373
|
+
onNone: () => "none",
|
|
374
|
+
onSome: DateTime.formatIso,
|
|
375
|
+
}),
|
|
376
|
+
sleepMs,
|
|
377
|
+
};
|
|
378
|
+
// An instance with nothing due should not emit a minutely INFO line
|
|
379
|
+
// forever; anything that acted or failed stays visible.
|
|
380
|
+
if (cycle.fanout === 0 && cycle.failures.length === 0) {
|
|
381
|
+
yield* Effect.logDebug("Schedule cycle complete", summary);
|
|
382
|
+
}
|
|
383
|
+
else {
|
|
384
|
+
yield* Effect.logInfo("Schedule cycle complete", summary);
|
|
385
|
+
}
|
|
386
|
+
yield* Effect.sleep(Duration.millis(sleepMs));
|
|
387
|
+
}).pipe(Effect.forever);
|
|
388
|
+
return { latest: Ref.get(latestCycle), run, tick };
|
|
389
|
+
}));
|
|
390
|
+
}
|
|
391
|
+
//# sourceMappingURL=schedule-triggers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schedule-triggers.js","sourceRoot":"","sources":["../src/schedule-triggers.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/** Configured FIFO worker scheduler: the platform-free Executor-to-engine adapter. */
|
|
2
|
+
import type { UsineConfig } from "@usine/config";
|
|
3
|
+
import { Executor, ExecutorError } from "@usine/executor";
|
|
4
|
+
import { StepExecutor } from "@usine/engine";
|
|
5
|
+
import { Layer, Schema } from "effect";
|
|
6
|
+
declare const UnsupportedWorkerError_base: Schema.Class<UnsupportedWorkerError, Schema.TaggedStruct<"UnsupportedWorkerError", {
|
|
7
|
+
readonly worker: Schema.brand<Schema.String, "WorkerName">;
|
|
8
|
+
readonly kind: Schema.String;
|
|
9
|
+
}>, import("effect/Cause").YieldableError>;
|
|
10
|
+
export declare class UnsupportedWorkerError extends UnsupportedWorkerError_base {
|
|
11
|
+
}
|
|
12
|
+
/** Configured FIFO worker scheduler and Executor-to-engine adapter. */
|
|
13
|
+
export declare const stepExecutorLayer: (config: UsineConfig) => Layer.Layer<StepExecutor, ExecutorError | UnsupportedWorkerError, Executor>;
|
|
14
|
+
export {};
|
|
15
|
+
//# sourceMappingURL=scheduler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scheduler.d.ts","sourceRoot":"","sources":["../src/scheduler.ts"],"names":[],"mappings":"AAAA,sFAAsF;AAEtF,OAAO,KAAK,EAA0B,WAAW,EAAE,MAAM,eAAe,CAAC;AAEzE,OAAO,EAEL,QAAQ,EACR,aAAa,EAEd,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,YAAY,EAAoB,MAAM,eAAe,CAAC;AAC/D,OAAO,EAIL,KAAK,EAKL,MAAM,EAEP,MAAM,QAAQ,CAAC;;;;;AAEhB,qBAAa,sBAAuB,SAAQ,2BAK1C;CAAG;AAoDL,uEAAuE;AACvE,eAAO,MAAM,iBAAiB,WACpB,WAAW,KAClB,KAAK,CAAC,KAAK,CAAC,YAAY,EAAE,aAAa,GAAG,sBAAsB,EAAE,QAAQ,CA+I1E,CAAC"}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/** Configured FIFO worker scheduler: the platform-free Executor-to-engine adapter. */
|
|
2
|
+
import { AttemptFailure, Worker } from "@usine/core";
|
|
3
|
+
import { CheckoutRequest, Executor, ExecutorError, } from "@usine/executor";
|
|
4
|
+
import { StepExecutor } from "@usine/engine";
|
|
5
|
+
import { DateTime, Deferred, Effect, Layer, Option, Order, Queue, Ref, Schema, TxPriorityQueue, } from "effect";
|
|
6
|
+
export class UnsupportedWorkerError extends Schema.TaggedError("@usine/orchestrator/UnsupportedWorkerError")("UnsupportedWorkerError", {
|
|
7
|
+
worker: Worker.Name,
|
|
8
|
+
kind: Schema.String,
|
|
9
|
+
}) {
|
|
10
|
+
}
|
|
11
|
+
const reservationOrder = Order.combine(Order.mapInput(Order.Number, (reservation) => reservation.eventTime), Order.mapInput(Order.Number, (reservation) => reservation.order));
|
|
12
|
+
const asInfrastructureFailure = (error) => new AttemptFailure.InfraFailure({
|
|
13
|
+
message: error._tag === "ExecutorOperationError"
|
|
14
|
+
? `Executor ${error.operation} failed: ${error.message}`
|
|
15
|
+
: error.message,
|
|
16
|
+
cause: error,
|
|
17
|
+
});
|
|
18
|
+
const makeLease = Effect.fn("WorkerScheduler.makeLease")(function* (worker, available) {
|
|
19
|
+
const released = yield* Ref.make(false);
|
|
20
|
+
return {
|
|
21
|
+
worker,
|
|
22
|
+
release: Ref.modify(released, (done) => [!done, true]).pipe(Effect.flatMap((first) => (first ? Queue.offer(available, worker) : Effect.void)), Effect.asVoid),
|
|
23
|
+
};
|
|
24
|
+
});
|
|
25
|
+
const validateWorkers = (kind, workers) => {
|
|
26
|
+
const unsupported = workers.find((worker) => worker.kind !== kind);
|
|
27
|
+
return unsupported === undefined
|
|
28
|
+
? Effect.succeed(workers)
|
|
29
|
+
: new UnsupportedWorkerError({ worker: unsupported.name, kind: unsupported.kind });
|
|
30
|
+
};
|
|
31
|
+
/** Configured FIFO worker scheduler and Executor-to-engine adapter. */
|
|
32
|
+
export const stepExecutorLayer = (config) => Layer.effect(StepExecutor, Effect.gen(function* () {
|
|
33
|
+
const executor = yield* Executor;
|
|
34
|
+
const workers = yield* validateWorkers(executor.kind, config.workers);
|
|
35
|
+
yield* Effect.forEach(workers, ({ name }) => executor.preflight(name), {
|
|
36
|
+
concurrency: "unbounded",
|
|
37
|
+
discard: true,
|
|
38
|
+
});
|
|
39
|
+
const available = yield* Queue.make();
|
|
40
|
+
yield* Queue.offerAll(available, workers.flatMap(({ maxConcurrentAttempts, name }) => Array.from({ length: maxConcurrentAttempts }, () => name)));
|
|
41
|
+
const pending = yield* TxPriorityQueue.empty(reservationOrder);
|
|
42
|
+
const nextOrder = yield* Ref.make(0);
|
|
43
|
+
const dispatch = Effect.forever(Effect.gen(function* () {
|
|
44
|
+
const worker = yield* Queue.take(available);
|
|
45
|
+
const reservation = yield* TxPriorityQueue.take(pending);
|
|
46
|
+
const lease = yield* makeLease(worker, available);
|
|
47
|
+
const assign = yield* Ref.modify(reservation.state, (state) => state._tag === "Pending"
|
|
48
|
+
? [true, { _tag: "Assigned", lease }]
|
|
49
|
+
: [false, state]);
|
|
50
|
+
if (assign) {
|
|
51
|
+
yield* Effect.logDebug("Worker slot assigned", { worker });
|
|
52
|
+
yield* Deferred.succeed(reservation.deferred, lease);
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
yield* lease.release;
|
|
56
|
+
}
|
|
57
|
+
}));
|
|
58
|
+
yield* Effect.forkScoped(dispatch);
|
|
59
|
+
const reserve = Effect.fn("WorkerScheduler.reserve")(function* (submission) {
|
|
60
|
+
const deferred = yield* Deferred.make();
|
|
61
|
+
const state = yield* Ref.make({ _tag: "Pending" });
|
|
62
|
+
const reservation = {
|
|
63
|
+
deferred,
|
|
64
|
+
eventTime: DateTime.toEpochMillis(submission.event.receivedAt),
|
|
65
|
+
order: yield* Ref.getAndUpdate(nextOrder, (value) => value + 1),
|
|
66
|
+
state,
|
|
67
|
+
};
|
|
68
|
+
yield* TxPriorityQueue.offer(pending, reservation);
|
|
69
|
+
return yield* Deferred.await(deferred).pipe(Effect.onInterrupt(() => Ref.modify(state, (current) => current._tag === "Assigned"
|
|
70
|
+
? [Option.some(current.lease), { _tag: "Canceled" }]
|
|
71
|
+
: [Option.none(), { _tag: "Canceled" }]).pipe(Effect.flatMap(Option.match({ onNone: () => Effect.void, onSome: (lease) => lease.release })))));
|
|
72
|
+
});
|
|
73
|
+
const execute = Effect.fn("WorkerScheduler.execute")(function* (execution, io) {
|
|
74
|
+
yield* Effect.annotateCurrentSpan({
|
|
75
|
+
attemptId: execution.attempt.id,
|
|
76
|
+
runId: execution.run.id,
|
|
77
|
+
worker: execution.attempt.worker,
|
|
78
|
+
});
|
|
79
|
+
// `prepare` stays interruptible — a cancel must be able to stop a
|
|
80
|
+
// hung clone or fetch; the adapter cleans its partial state on any
|
|
81
|
+
// non-success exit.
|
|
82
|
+
const prepared = yield* executor
|
|
83
|
+
.prepare(new CheckoutRequest({
|
|
84
|
+
attemptId: execution.attempt.id,
|
|
85
|
+
worker: execution.attempt.worker,
|
|
86
|
+
repository: execution.repository,
|
|
87
|
+
revision: execution.revision,
|
|
88
|
+
payload: execution.event.payload,
|
|
89
|
+
task: execution.task,
|
|
90
|
+
agent: execution.agent,
|
|
91
|
+
parentModel: execution.parentModel,
|
|
92
|
+
}))
|
|
93
|
+
.pipe(Effect.mapError(asInfrastructureFailure));
|
|
94
|
+
return yield* executor.launch(prepared, io).pipe(Effect.onInterrupt(() => executor.cancel(execution.attempt.id).pipe(Effect.tapError((error) => Effect.logWarning("Cancel-on-interrupt failed", {
|
|
95
|
+
attemptId: execution.attempt.id,
|
|
96
|
+
message: error.message,
|
|
97
|
+
})), Effect.ignore)),
|
|
98
|
+
// The attempt dies before its credential grant does: a hung run
|
|
99
|
+
// host or dead link past the configured budget interrupts the
|
|
100
|
+
// launch (running the cancel handshake above) and reports a typed
|
|
101
|
+
// infra failure, never a silent forever-park (ADR 0006).
|
|
102
|
+
Effect.timeoutOrElse({
|
|
103
|
+
duration: `${config.settings.maxAttemptMinutes} minutes`,
|
|
104
|
+
orElse: () => Effect.fail(new AttemptFailure.InfraFailure({
|
|
105
|
+
message: `Attempt exceeded the ${config.settings.maxAttemptMinutes}-minute budget`,
|
|
106
|
+
cause: new Error("attempt timeout"),
|
|
107
|
+
})),
|
|
108
|
+
}),
|
|
109
|
+
// ADR 0006: the worktree dies at attempt end regardless of outcome.
|
|
110
|
+
// Cleanup never decides that outcome — a failed removal is logged,
|
|
111
|
+
// not allowed to convert a finished agent session into a retryable
|
|
112
|
+
// infra failure that would re-run non-idempotent work.
|
|
113
|
+
Effect.ensuring(executor.cleanup(prepared).pipe(Effect.tapError((error) => Effect.logError("Attempt cleanup failed; the worktree may need manual removal", {
|
|
114
|
+
attemptId: execution.attempt.id,
|
|
115
|
+
worktree: prepared.worktree,
|
|
116
|
+
message: error.message,
|
|
117
|
+
})), Effect.ignore)));
|
|
118
|
+
});
|
|
119
|
+
const interrupt = (attemptId) => executor.cancel(attemptId).pipe(Effect.mapError(asInfrastructureFailure));
|
|
120
|
+
return StepExecutor.of({ execute, interrupt, reserve });
|
|
121
|
+
}));
|
|
122
|
+
//# sourceMappingURL=scheduler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scheduler.js","sourceRoot":"","sources":["../src/scheduler.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { type ConfigFileError, type LoadedInstance, type LoopFile, type ManagedRepo } from "@usine/config";
|
|
2
|
+
import { Agent, AttemptChannel, Event, Item } from "@usine/core";
|
|
3
|
+
import { Submission, type SubmissionResult } from "@usine/engine";
|
|
4
|
+
import { type DateTime, Effect, Option, Schema } from "effect";
|
|
5
|
+
export interface ResolvedLoop {
|
|
6
|
+
readonly agent: Agent.Agent;
|
|
7
|
+
readonly loop: LoopFile;
|
|
8
|
+
readonly parentModel: Option.Option<Agent.ModelId>;
|
|
9
|
+
}
|
|
10
|
+
declare const LoopAgentResolutionError_base: Schema.Class<LoopAgentResolutionError, Schema.TaggedStruct<"LoopAgentResolutionError", {
|
|
11
|
+
readonly loop: Schema.brand<Schema.NonEmptyString, "LoopName">;
|
|
12
|
+
readonly agent: Schema.brand<Schema.String, "AgentName">;
|
|
13
|
+
readonly message: Schema.NonEmptyString;
|
|
14
|
+
}>, import("effect/Cause").YieldableError>;
|
|
15
|
+
/** A loaded loop lost the roster member its authored agent name refers to. */
|
|
16
|
+
export declare class LoopAgentResolutionError extends LoopAgentResolutionError_base {
|
|
17
|
+
}
|
|
18
|
+
/** Snapshot one authored loop's roster member and effective parent model. */
|
|
19
|
+
export declare const resolveTriggerLoop: (instance: LoadedInstance, loop: LoopFile) => Effect.Effect<{
|
|
20
|
+
agent: Agent.Agent;
|
|
21
|
+
loop: LoopFile;
|
|
22
|
+
parentModel: Option.Option<string & import("effect/Brand").Brand<"ModelId">>;
|
|
23
|
+
}, LoopAgentResolutionError, never>;
|
|
24
|
+
/**
|
|
25
|
+
* Snapshot the validated instance roster. `InstanceFolder.load` quarantines
|
|
26
|
+
* loops naming unknown Agents, so a miss here is config drift on a
|
|
27
|
+
* hand-assembled instance: the loop is skipped with a log every cycle while
|
|
28
|
+
* its siblings keep polling — the same isolation the schedule path applies.
|
|
29
|
+
*/
|
|
30
|
+
export declare const resolveTriggerLoops: (instance: LoadedInstance) => Effect.Effect<ResolvedLoop[], never, never>;
|
|
31
|
+
interface TriggerSubmissionOptions {
|
|
32
|
+
readonly agent: Agent.Agent;
|
|
33
|
+
readonly dedupKey: Event.DedupKey;
|
|
34
|
+
readonly itemKey: Item.ItemKey;
|
|
35
|
+
readonly loop: LoopFile;
|
|
36
|
+
readonly payload: Schema.Json;
|
|
37
|
+
readonly receivedAt: DateTime.Utc;
|
|
38
|
+
readonly repository: ManagedRepo;
|
|
39
|
+
readonly task: AttemptChannel.Task;
|
|
40
|
+
readonly parentModel: Option.Option<Agent.ModelId>;
|
|
41
|
+
}
|
|
42
|
+
/** The one routing contract shared by every trigger stream. */
|
|
43
|
+
export declare const triggerSubmission: (options: TriggerSubmissionOptions) => Submission;
|
|
44
|
+
/**
|
|
45
|
+
* What each submission outcome contributes to its log line: the run for a
|
|
46
|
+
* claim, the ignore reason for a superseded or revoked Event — never a
|
|
47
|
+
* sentinel value.
|
|
48
|
+
*/
|
|
49
|
+
export declare const submissionLogFields: (submission: SubmissionResult) => Record<string, string>;
|
|
50
|
+
/** Safe structured context for a config-owned trigger failure. */
|
|
51
|
+
export declare const configFileErrorLogFields: (error: ConfigFileError) => {
|
|
52
|
+
configFile: string & import("effect/Brand").Brand<"InstancePath">;
|
|
53
|
+
configStage: "expression" | "frontmatter" | "read" | "reference" | "schema" | "yaml";
|
|
54
|
+
} | {
|
|
55
|
+
configFile: string & import("effect/Brand").Brand<"InstancePath">;
|
|
56
|
+
configStage: "expression" | "frontmatter" | "read" | "reference" | "schema" | "yaml";
|
|
57
|
+
expression: string & import("effect/Brand").Brand<"ExpressionSource">;
|
|
58
|
+
};
|
|
59
|
+
export {};
|
|
60
|
+
//# sourceMappingURL=trigger-submission.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trigger-submission.d.ts","sourceRoot":"","sources":["../src/trigger-submission.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,eAAe,EACpB,KAAK,cAAc,EACnB,KAAK,QAAQ,EACb,KAAK,WAAW,EACjB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,IAAI,EAAoB,MAAM,aAAa,CAAC;AACnF,OAAO,EAAE,UAAU,EAAE,KAAK,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAClE,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,EAAS,MAAM,EAAU,MAAM,EAAE,MAAM,QAAQ,CAAC;AAQ9E,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC;IAC5B,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IACxB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;CACpD;;;;;;AAED,8EAA8E;AAC9E,qBAAa,wBAAyB,SAAQ,6BAM5C;CAAG;AAEL,6EAA6E;AAC7E,eAAO,MAAM,kBAAkB;;;;mCA6B7B,CAAC;AAEH;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,2EAkB9B,CAAC;AAEH,UAAU,wBAAwB;IAChC,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC;IAC5B,QAAQ,CAAC,QAAQ,EAAE,KAAK,CAAC,QAAQ,CAAC;IAClC,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC;IAC/B,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,IAAI,CAAC;IAC9B,QAAQ,CAAC,UAAU,EAAE,QAAQ,CAAC,GAAG,CAAC;IAClC,QAAQ,CAAC,UAAU,EAAE,WAAW,CAAC;IACjC,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAC,IAAI,CAAC;IACnC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;CACpD;AAED,+DAA+D;AAC/D,eAAO,MAAM,iBAAiB,YAAa,wBAAwB,KAAG,UAiBlE,CAAC;AAEL;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,eAAgB,gBAAgB,KAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAKpF,CAAC;AAEL,kEAAkE;AAClE,eAAO,MAAM,wBAAwB,UAAW,eAAe;;;;;;;CAQ3D,CAAC"}
|