fix: Scope crash-retry budget to launch failures - #29
Merged
Conversation
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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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.