Commit e21dca0
Robust daemon lifecycle management and safety improvements (#118)
## Summary
This PR comprehensively improves daemon lifecycle management, addressing
multiple issues around daemon startup, shutdown, and process safety.
### Core Changes
- **Fix update command creating multiple daemons** - Use `stopDaemon()`
and `killAllDaemons()` instead of HTTP POST to ensure old daemon is
properly killed before starting new one
- **Highlander mode** - Prevent multiple daemons from running
simultaneously by detecting and cleaning up existing instances at
startup
- **Per-PID runtime files** - Use `daemon.$PID.json` pattern instead of
single `daemon.json` to properly track multiple daemon instances and
enable reliable cleanup
### Safety Improvements
- **PID reuse protection** - Tri-state process identity checking
(`processIsRoborev`, `processNotRoborev`, `processUnknown`) prevents
killing unrelated processes if a PID is reused
- **Conservative unknown handling** - When process identity can't be
determined (permissions, missing tools), keep runtime file to avoid
orphaning running daemons
- **Loopback validation** - Strict address validation prevents SSRF via
malicious runtime files; only allows HTTP calls to 127.x.x.x, ::1, and
localhost
- **Invalid runtime cleanup** - Remove runtime files with invalid data
(pid <= 0, empty addr) during listing
### Reliability Improvements
- **IsDaemonAlive retry logic** - 2 attempts with 1s timeout to avoid
false negatives on slow or transiently failing daemons
- **Windows locale-independent detection** - Use `tasklist /FO CSV` and
`wmic` for process detection instead of parsing localized strings
- **PowerShell fallback** - Use `Get-CimInstance` on Windows systems
without `wmic` (common on newer Win11)
- **UTF-16 BOM handling** - Properly handle UTF-16LE/BE encoded output
from Windows tools
### TUI Improvements
- **Daemon reconnection** - TUI sessions now automatically reconnect if
daemon restarts on a different port. After 3 consecutive connection
failures, the TUI re-reads runtime files to find the new daemon address.
## Test plan
- [x] Run `roborev update --force` and verify only one daemon process
running
- [x] All daemon tests pass on macOS
- [x] TUI reconnection tests pass
- [ ] CI passes on Linux and Windows
- [ ] `pgrep -fl "roborev daemon"` shows only one process after update
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>1 parent 6895ad5 commit e21dca0
File tree
12 files changed
+1828
-86
lines changed- cmd/roborev
- internal/daemon
12 files changed
+1828
-86
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
5 | 5 | | |
6 | 6 | | |
7 | 7 | | |
8 | | - | |
9 | 8 | | |
10 | 9 | | |
11 | 10 | | |
| |||
82 | 81 | | |
83 | 82 | | |
84 | 83 | | |
85 | | - | |
| 84 | + | |
86 | 85 | | |
87 | 86 | | |
88 | 87 | | |
| |||
93 | 92 | | |
94 | 93 | | |
95 | 94 | | |
96 | | - | |
97 | | - | |
| 95 | + | |
| 96 | + | |
98 | 97 | | |
99 | 98 | | |
100 | 99 | | |
| |||
165 | 164 | | |
166 | 165 | | |
167 | 166 | | |
168 | | - | |
| 167 | + | |
169 | 168 | | |
170 | 169 | | |
171 | 170 | | |
| |||
182 | 181 | | |
183 | 182 | | |
184 | 183 | | |
185 | | - | |
186 | | - | |
187 | | - | |
188 | | - | |
| 184 | + | |
| 185 | + | |
189 | 186 | | |
190 | | - | |
| 187 | + | |
191 | 188 | | |
| 189 | + | |
192 | 190 | | |
193 | 191 | | |
194 | 192 | | |
195 | | - | |
196 | | - | |
197 | | - | |
198 | | - | |
199 | | - | |
200 | | - | |
201 | | - | |
202 | | - | |
203 | | - | |
204 | | - | |
205 | | - | |
| 193 | + | |
| 194 | + | |
206 | 195 | | |
207 | | - | |
208 | | - | |
| 196 | + | |
209 | 197 | | |
210 | 198 | | |
211 | 199 | | |
212 | | - | |
213 | | - | |
214 | | - | |
215 | | - | |
216 | | - | |
217 | | - | |
218 | | - | |
219 | | - | |
220 | | - | |
221 | | - | |
222 | | - | |
223 | | - | |
224 | | - | |
225 | | - | |
| 200 | + | |
| 201 | + | |
| 202 | + | |
| 203 | + | |
| 204 | + | |
| 205 | + | |
| 206 | + | |
| 207 | + | |
| 208 | + | |
226 | 209 | | |
227 | 210 | | |
228 | 211 | | |
229 | 212 | | |
230 | 213 | | |
231 | 214 | | |
232 | | - | |
233 | | - | |
234 | | - | |
235 | | - | |
| 215 | + | |
| 216 | + | |
236 | 217 | | |
237 | | - | |
| 218 | + | |
238 | 219 | | |
239 | 220 | | |
240 | 221 | | |
| |||
2038 | 2019 | | |
2039 | 2020 | | |
2040 | 2021 | | |
2041 | | - | |
2042 | | - | |
| 2022 | + | |
| 2023 | + | |
2043 | 2024 | | |
2044 | | - | |
2045 | | - | |
2046 | | - | |
2047 | | - | |
2048 | | - | |
2049 | | - | |
2050 | | - | |
2051 | | - | |
2052 | | - | |
| 2025 | + | |
| 2026 | + | |
| 2027 | + | |
| 2028 | + | |
2053 | 2029 | | |
2054 | 2030 | | |
2055 | 2031 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
8 | 8 | | |
9 | 9 | | |
10 | 10 | | |
11 | | - | |
12 | 11 | | |
13 | 12 | | |
14 | | - | |
15 | 13 | | |
16 | 14 | | |
17 | 15 | | |
| |||
39 | 37 | | |
40 | 38 | | |
41 | 39 | | |
42 | | - | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
43 | 56 | | |
44 | 57 | | |
45 | 58 | | |
| |||
1531 | 1544 | | |
1532 | 1545 | | |
1533 | 1546 | | |
1534 | | - | |
1535 | | - | |
| 1547 | + | |
| 1548 | + | |
| 1549 | + | |
1536 | 1550 | | |
1537 | 1551 | | |
1538 | 1552 | | |
1539 | 1553 | | |
1540 | 1554 | | |
| 1555 | + | |
| 1556 | + | |
| 1557 | + | |
1541 | 1558 | | |
1542 | 1559 | | |
1543 | | - | |
| 1560 | + | |
1544 | 1561 | | |
1545 | 1562 | | |
1546 | 1563 | | |
| |||
1611 | 1628 | | |
1612 | 1629 | | |
1613 | 1630 | | |
1614 | | - | |
1615 | | - | |
| 1631 | + | |
| 1632 | + | |
| 1633 | + | |
| 1634 | + | |
| 1635 | + | |
1616 | 1636 | | |
1617 | 1637 | | |
1618 | 1638 | | |
| |||
1652 | 1672 | | |
1653 | 1673 | | |
1654 | 1674 | | |
1655 | | - | |
1656 | | - | |
1657 | | - | |
1658 | | - | |
1659 | | - | |
1660 | | - | |
1661 | | - | |
1662 | | - | |
1663 | | - | |
1664 | | - | |
| 1675 | + | |
| 1676 | + | |
| 1677 | + | |
| 1678 | + | |
1665 | 1679 | | |
1666 | 1680 | | |
1667 | 1681 | | |
| |||
0 commit comments