|
@@ -108,52 +108,56 @@ namespace ClankerSaddle.Services {
|
|
|
*/
|
|
*/
|
|
|
public async void tick() throws Error {
|
|
public async void tick() throws Error {
|
|
|
var scope = container.create_scope();
|
|
var scope = container.create_scope();
|
|
|
- var tasks = scope.resolve<TaskService>();
|
|
|
|
|
- var saddles = scope.resolve<SaddleService>();
|
|
|
|
|
- var capabilities = scope.resolve<CapabilityService>();
|
|
|
|
|
- var allocation = scope.resolve<AllocationService>();
|
|
|
|
|
|
|
+ try {
|
|
|
|
|
+ var tasks = scope.resolve<TaskService>();
|
|
|
|
|
+ var saddles = scope.resolve<SaddleService>();
|
|
|
|
|
+ var capabilities = scope.resolve<CapabilityService>();
|
|
|
|
|
+ var allocation = scope.resolve<AllocationService>();
|
|
|
|
|
|
|
|
- if (LlmEndpoint.from_environment() == null) {
|
|
|
|
|
- if (!warned_no_llm) {
|
|
|
|
|
- warning("[ClankerSaddle] SADDLE_LLM_BASE_URL is not set; task assignment is paused");
|
|
|
|
|
- warned_no_llm = true;
|
|
|
|
|
|
|
+ if (LlmEndpoint.from_environment() == null) {
|
|
|
|
|
+ if (!warned_no_llm) {
|
|
|
|
|
+ warning("[ClankerSaddle] SADDLE_LLM_BASE_URL is not set; task assignment is paused");
|
|
|
|
|
+ warned_no_llm = true;
|
|
|
|
|
+ }
|
|
|
|
|
+ } else {
|
|
|
|
|
+ warned_no_llm = false;
|
|
|
|
|
+ yield enforce_lost_wake_guard(saddles, tasks);
|
|
|
|
|
+ yield wake_sleeping_saddles(saddles, capabilities, allocation);
|
|
|
}
|
|
}
|
|
|
- } else {
|
|
|
|
|
- warned_no_llm = false;
|
|
|
|
|
- yield enforce_lost_wake_guard(saddles, tasks);
|
|
|
|
|
- yield wake_sleeping_saddles(saddles, capabilities, allocation);
|
|
|
|
|
- }
|
|
|
|
|
|
|
|
|
|
- yield saddles.requeue_tasks_on_offline_saddles(tasks);
|
|
|
|
|
|
|
+ yield saddles.requeue_tasks_on_offline_saddles(tasks);
|
|
|
|
|
|
|
|
- // Web Push retry tick (plan 11 task E): anything a failed
|
|
|
|
|
- // send left queued retries here (best-effort delivery).
|
|
|
|
|
- yield push.flush();
|
|
|
|
|
|
|
+ // Web Push retry tick (plan 11 task E): anything a failed
|
|
|
|
|
+ // send left queued retries here (best-effort delivery).
|
|
|
|
|
+ yield push.flush();
|
|
|
|
|
|
|
|
- foreach (var saddle in yield saddles.list_busy_saddles()) {
|
|
|
|
|
- // The derived busy pass (plan 16 item 23): each busy
|
|
|
|
|
- // saddle's running work IS its open session on an
|
|
|
|
|
- // assigned/working task — the ONE truth accessor
|
|
|
|
|
- // resolves it (a saddle whose work closed between the
|
|
|
|
|
- // two reads reads idle next tick; nothing to do).
|
|
|
|
|
- var work = yield saddles.current_work_view(saddle);
|
|
|
|
|
- if (work == null) {
|
|
|
|
|
- continue;
|
|
|
|
|
- }
|
|
|
|
|
- // Human comments ride POST /task-update to the RUNNING
|
|
|
|
|
- // daemon (best effort — a transport failure stays
|
|
|
|
|
- // undelivered for the next tick; the staleness probe
|
|
|
|
|
- // owns the daemon's fate, not a strike counter).
|
|
|
|
|
- try {
|
|
|
|
|
- yield saddles.deliver_pending_comments(saddle.id, ((!)work).task_id);
|
|
|
|
|
- } catch (Error e) {
|
|
|
|
|
- warning(@"[ClankerSaddle] Comment delivery to saddle $(saddle.id) failed: $(e.message)");
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ foreach (var saddle in yield saddles.list_busy_saddles()) {
|
|
|
|
|
+ // The derived busy pass (plan 16 item 23): each busy
|
|
|
|
|
+ // saddle's running work IS its open session on an
|
|
|
|
|
+ // assigned/working task — the ONE truth accessor
|
|
|
|
|
+ // resolves it (a saddle whose work closed between the
|
|
|
|
|
+ // two reads reads idle next tick; nothing to do).
|
|
|
|
|
+ var work = yield saddles.current_work_view(saddle);
|
|
|
|
|
+ if (work == null) {
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+ // Human comments ride POST /task-update to the RUNNING
|
|
|
|
|
+ // daemon (best effort — a transport failure stays
|
|
|
|
|
+ // undelivered for the next tick; the staleness probe
|
|
|
|
|
+ // owns the daemon's fate, not a strike counter).
|
|
|
|
|
+ try {
|
|
|
|
|
+ yield saddles.deliver_pending_comments(saddle.id, ((!)work).task_id);
|
|
|
|
|
+ } catch (Error e) {
|
|
|
|
|
+ warning(@"[ClankerSaddle] Comment delivery to saddle $(saddle.id) failed: $(e.message)");
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- if (poll_state.take_stale_probe(((!)work).session_id,
|
|
|
|
|
- SaddleService.stale_after_seconds() * 1000)) {
|
|
|
|
|
- yield saddles.probe_stale_saddle(saddle, tasks, ((!)work).task_id);
|
|
|
|
|
|
|
+ if (poll_state.take_stale_probe(((!)work).session_id,
|
|
|
|
|
+ SaddleService.stale_after_seconds() * 1000)) {
|
|
|
|
|
+ yield saddles.probe_stale_saddle(saddle, tasks, ((!)work).task_id);
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
+ } finally {
|
|
|
|
|
+ scope.release();
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|