Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions cmd/claw-api/scheduler.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ type dispatchOptions struct {

const defaultWakeExecTimeout = 30 * time.Second
const openclawWakeExecTimeout = schedulepkg.MaxWakeExecTimeout
const hermesWakeExecTimeout = schedulepkg.MaxWakeExecTimeout

var errScheduleInvocationInFlight = errors.New("schedule invocation already in flight")

Expand Down Expand Up @@ -610,6 +611,8 @@ func wakeExecTimeout(adapter string) time.Duration {
switch strings.TrimSpace(adapter) {
case "openclaw-exec":
return openclawWakeExecTimeout
case "hermes-exec":
return hermesWakeExecTimeout
default:
return defaultWakeExecTimeout
}
Expand Down
7 changes: 5 additions & 2 deletions cmd/claw-api/scheduler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,14 @@ func TestShouldAttemptDegradedThrottlesToRoughlyTenPercent(t *testing.T) {
}
}

func TestWakeExecTimeoutUsesOpenClawBudget(t *testing.T) {
func TestWakeExecTimeoutUsesRunnerSpecificBudgets(t *testing.T) {
if got := wakeExecTimeout("openclaw-exec"); got != openclawWakeExecTimeout {
t.Fatalf("expected openclaw wake timeout %v, got %v", openclawWakeExecTimeout, got)
}
if got := wakeExecTimeout("hermes-exec"); got != defaultWakeExecTimeout {
if got := wakeExecTimeout("hermes-exec"); got != hermesWakeExecTimeout {
t.Fatalf("expected hermes wake timeout %v, got %v", hermesWakeExecTimeout, got)
}
if got := wakeExecTimeout("nanobot-exec"); got != defaultWakeExecTimeout {
t.Fatalf("expected default wake timeout %v, got %v", defaultWakeExecTimeout, got)
}
}
Expand Down
1 change: 1 addition & 0 deletions site/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ outline: deep

- **Slow scheduled wakes no longer block unrelated targets** -- claw-api dispatches due targets concurrently while serializing wakes per runner, coalesces overlapping slots without regressing next-fire state, rejects duplicate manual fires with a conflict, and drains active scheduler dispatches cleanly on shutdown. Coalesced slots are now recorded in schedule state (`suppressed_slots`, `last_suppressed_at`) and surfaced on the clawdash schedule card, so a schedule whose wake outruns its own cadence no longer reads as perfectly healthy. Closes [#347](https://github.com/mostlydev/clawdapus/issues/347).
- **Manual schedule fires honor runner wake budgets** -- `claw api schedule fire` now gives the in-container request 2 minutes 5 seconds and its outer compose transport 2 minutes 10 seconds, enough to return the final result of the longest supported runner wake. Other schedule operations retain their short defaults, and an explicit `--exec-timeout` still overrides the outer transport. Closes [#348](https://github.com/mostlydev/clawdapus/issues/348).
- **Hermes scheduled wakes get a runner-sized timeout** -- claw-api now gives `hermes-exec` the same two-minute wake budget as other runner-native cron paths, preventing a successfully triggered Hermes job from being recorded as `exec timed out` solely because the runner took longer than the generic 30-second transport budget. Closes [#345](https://github.com/mostlydev/clawdapus/issues/345).

## v0.27.0 <Badge type="tip" text="Latest" /> {#v0-27-0}

Expand Down
Loading