Skip to content

fix: Scope crash-retry budget to launch failures - #29

Merged
ResurrectedTrader merged 1 commit into
mainfrom
analysis/heartbeat
Aug 23, 2026
Merged

fix: Scope crash-retry budget to launch failures#29
ResurrectedTrader merged 1 commit into
mainfrom
analysis/heartbeat

Conversation

@ResurrectedTrader

Copy link
Copy Markdown
Owner

Heartbeat timeouts, hung windows, unexpected exits and any exception escaping RunProfileAsync all fed one lifetime CrashCount, capped at 5 and reset only by a manual start. Time-to-give-up was therefore a function of uptime alone: at a couple of transient faults a day a profile was absorbed after roughly two days and had its schedule disabled, whether or not anything was actually wrong with it.

D2Bot# kept these concerns separate. Its budget (Crashed, cap 6) was incremented only from the two LoadRemoteLibrary catch blocks and cleared on every successful load, while the heartbeat and Responding watchdogs restarted unconditionally and forever, and no failure path ever touched ScheduleEnable.

  • Split CrashCount into LaunchFailureCount (the budget, cleared by any successful launch) and RuntimeRestartCount (drives backoff, never fatal).
  • Back runtime restarts off from 5s to a 5min ceiling instead of a flat 5s delay and a hard cap. Reset only after a run stays up 60s and reports in, so a crash-looping bot cannot zero its own backoff.
  • Stop writing ScheduleEnabled = false on exhaustion; leave schedule recovery to ScheduleEngine, and the stopSchedule message as the way a script opts out.
  • Record heartbeat liveness on the message pump rather than at dispatch, so a backed-up queue no longer reads as a dead bot. kolbot's heartbeat thread sends mode 0xBBBB at 1Hz, so heartbeats no longer enter the shared queue at all.
  • Store the registered game window handle on the instance. Removals keyed on a live Process.GameWindow re-read no-opped once the process had exited, leaking a routing entry per launch and letting the handoff snapshot hand a successor a dead handle. Warn on unrouted messages instead of dropping them into Debug.
  • Run restart/stop off the message loop, and drop the hung-window probe from 1Hz to 5s using the cached handle instead of an EnumWindows sweep per second.

Heartbeat timeouts, hung windows, unexpected exits and any exception escaping
RunProfileAsync all fed one lifetime CrashCount, capped at 5 and reset only by a
manual start. Time-to-give-up was therefore a function of uptime alone: at a
couple of transient faults a day a profile was absorbed after roughly two days
and had its schedule disabled, whether or not anything was actually wrong with
it.

D2Bot# kept these concerns separate. Its budget (Crashed, cap 6) was incremented
only from the two LoadRemoteLibrary catch blocks and cleared on every successful
load, while the heartbeat and Responding watchdogs restarted unconditionally and
forever, and no failure path ever touched ScheduleEnable.

- Split CrashCount into LaunchFailureCount (the budget, cleared by any
  successful launch) and RuntimeRestartCount (drives backoff, never fatal).
- Back runtime restarts off from 5s to a 5min ceiling instead of a flat 5s delay
  and a hard cap. Reset only after a run stays up 60s and reports in, so a
  crash-looping bot cannot zero its own backoff.
- Stop writing ScheduleEnabled = false on exhaustion; leave schedule recovery to
  ScheduleEngine, and the stopSchedule message as the way a script opts out.
- Record heartbeat liveness on the message pump rather than at dispatch, so a
  backed-up queue no longer reads as a dead bot. kolbot's heartbeat thread sends
  mode 0xBBBB at 1Hz, so heartbeats no longer enter the shared queue at all.
- Store the registered game window handle on the instance. Removals keyed on a
  live Process.GameWindow re-read no-opped once the process had exited, leaking
  a routing entry per launch and letting the handoff snapshot hand a successor a
  dead handle. Warn on unrouted messages instead of dropping them into Debug.
- Run restart/stop off the message loop, and drop the hung-window probe from 1Hz
  to 5s using the cached handle instead of an EnumWindows sweep per second.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@ResurrectedTrader
ResurrectedTrader merged commit ae57b50 into main Aug 23, 2026
7 checks passed
@ResurrectedTrader
ResurrectedTrader deleted the analysis/heartbeat branch August 23, 2026 20:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant