Fix Windows daemon restart and self-update flow#1076
Conversation
| self.shutdown_condvar.notify_all(); | ||
| } |
There was a problem hiding this comment.
🟡 Explicit Shutdown control request does not reset shutdown_action, causing unintended restart
When the update check loop or uptime check calls request_restart() or request_restart_after_update(), they store a non-Stop value in shutdown_action before calling request_shutdown(). However, an explicit ControlRequest::Shutdown (e.g. from git-ai bg shutdown) at src/daemon.rs:7389 only calls request_shutdown(), which never resets shutdown_action back to Stop. If the timing aligns (update/uptime check sets a restart intent, then user sends an explicit shutdown before the daemon finishes draining), the daemon will still attempt to restart in src/commands/daemon.rs:199-200 despite the explicit stop request. The request_shutdown method at src/daemon.rs:3760 should reset shutdown_action to DaemonExitAction::Stop so that an explicit shutdown always overrides a previously-set restart intent.
(Refers to lines 3760-3773)
Prompt for agents
The problem is in ActorDaemonCoordinator::request_shutdown (src/daemon.rs around line 3760). This method sets shutting_down to true and notifies waiters, but it does NOT reset shutdown_action to DaemonExitAction::Stop. The request_restart and request_restart_after_update methods store a non-Stop value in shutdown_action BEFORE calling request_shutdown. An explicit ControlRequest::Shutdown (processed at src/daemon.rs:7389) calls request_shutdown() which preserves the restart intent.
To fix: request_shutdown should reset shutdown_action to Stop, ensuring that any explicit shutdown overrides a previously set restart intent. The request_restart and request_restart_after_update methods already store their desired action before calling request_shutdown, so the ordering needs to be: request_restart stores the action, then request_shutdown would normally reset it — this won't work.
Alternative approach: Instead of modifying request_shutdown, add a separate request_stop method that resets shutdown_action to Stop and then calls request_shutdown, and use it from the ControlRequest::Shutdown handler at line 7389. Or, reverse the order in request_restart/request_restart_after_update to call request_shutdown first and then store the action (using a compare-and-swap to avoid overwriting a Stop that was set by an explicit shutdown). The cleanest approach is probably to make the Shutdown control handler explicitly store DaemonExitAction::Stop before calling request_shutdown.
Was this helpful? React with 👍 or 👎 to provide feedback.
There was a problem hiding this comment.
Patched this by adding an explicit request_stop() path and using it for ControlRequest::Shutdown, so a user-initiated stop now overrides any previously queued restart or restart-after-update intent. I also reran the daemon restart/update lifecycle tests locally after the change.
Summary
$PIDloop bug and add a regression testTesting
cargo test --package git-ai --test windows_install_script -- --nocapturecargo fmt -- --checkManual validation
$PIDloop variable