Commit Graph
4 Commits
Author SHA1 Message Date
DanSandClaude Opus 4.8 2c9e99c022 perf(daemon): memoize the external debug.log miss
When following the debug.log of a node this session did not launch, every
poll re-read the last 2 MB of the file and re-scanned it for the process
banner. If that node logs to its console instead, the banner is never
there, so the full re-scan repeated on every poll for the life of the
process.

- A miss is now remembered by pid and file size: if nothing has changed
  since the last miss, or the file is growing but the backoff has not
  elapsed, the scan is skipped.
- The retry schedule re-scans quickly during a fresh-node grace window
  (the banner flushes a beat after the pid appears) and then backs off
  from 4 s, doubling to a 60 s cap. The memo is cleared on a successful
  tie and when the followed process goes away.

Tests: the retry delay is fast within the grace window and then steps
4, 8, 16 s up to the 60 s cap.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-10-13 17:42:30 -05:00
DanSandClaude Opus 5.5 a3361020d1 feat(daemon): recognise our detached node, tail POSIX debug.log, more RPC threads
S12 - our node across sessions:
- The node the wallet launches is recorded in <datadir>/obsidiandragon-
  dragonxd.pid (pid + process start time + exe). A later session that
  finds it still running (after "Leave running" / keep_daemon_running)
  stops it gracefully on quit and waits for that exact process (no time
  limit, "Leave running" offered); never signals or kills it. A reused
  pid or a reboot never matches; stale records are deleted.
- stop_external_daemon is now honoured when this session only connected
  (no controller); it was ignored.

S13 - the node's own log on every platform:
- No -printtoconsole on Linux/macOS: the node writes its timestamped
  debug.log (which outlives the GUI) and we tail it next to the stderr
  pipe. Tail path from the datadir or the isolated override (Windows had
  %APPDATA% hard-coded, wrong for migrate-to-seed starts).
- After the node shrinks debug.log at startup, resume at this run's
  banner instead of re-reading the old run's tail.
- A node we didn't launch (left running, or found running) feeds the
  busy tracker from its debug.log, tied to the live process (our record,
  or POSIX hushd.pid) and only from lines it wrote. A GUI attaching to a
  node mid-rebuild now says "Node busy: rebuilding note witnesses" and
  asks before stopping it.
- A start that only finds a running node no longer resets the tracker;
  a found busy node shows the busy overlay at once.

S14: launch our node with -rpcthreads=16 unless DRAGONX.conf sets it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 12:06:52 -05:00
DanSandClaude Opus 5.5 1215ded1a0 feat(ui): say "Node busy" instead of "Launching dragonxd"; honest quit copy
A node rebuilding note witnesses for an hour was shown as "Starting
DragonX node... Launching dragonxd", which invited closing it.

- Overlay, a new NodeBusy banner and the status bar now say what the node
  is doing (rebuilding witnesses / catching up on blocks / up but not
  answering), with the elapsed time and Phase-1 block progress. A rebuild
  during startup warm-up replaces the stale "-28 Activating best chain"
  text, and the overlay re-applies its text once a second instead of only
  on a connect attempt (30s apart while the node is busy).
- Quit prompt: elapsed time, "Keep node running & quit" is the default,
  "Stop anyway & quit" becomes "Stop node & wait" (it no longer kills).
- A reinstall skipped because the node is still running now notifies.
- Status bar: don't repeat the warm-up status on the right, and don't
  print "Connected" there in non-English locales.
- i18n: 31 new keys in all 8 languages; 10 dead force-quit/old-modal keys
  removed; CJK subset rebuilt for the new glyphs.
- Tests: chooseDaemonStatus, NodeBusy banner priority, and every new key
  present in all 8 JSONs with matching printf conversions.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 10:26:32 -05:00
DanSandClaude Opus 5.5 6b14098bb2 fix(daemon): make the "keep the node running?" prompt actually appear
Quitting during a witness rebuild is supposed to ask before stopping the
node, because a stop throws the rebuild away and a killed node replays
and redoes it. The guard almost never fired:
- it returned false for any daemon >= v1.3.0, on the false premise that
  v1.3.0 checkpoints a rebuild (it does not; nothing survives a kill)
- it read a 16 KB debug.log tail and compared the last progress line with
  the newest line, so any unrelated line during the rebuild's silent
  second phase turned it off; and on POSIX that file is stale
- daemon_version, which the bypass needed, is zeroed when a busy node
  drops the connection

Now a DaemonBusyTracker (src/daemon/daemon_busy_detect.h, pure) follows
dragonxd's own markers in order: rebuilding (Phase-1 / legacy markers,
ended by the completion line, an abort line or the next UpdateTip) and
replaying (Activating best chain ... Done Loading), reset by a new banner
or "Shutdown: done". It is fed from the owned output on the UI thread,
including the backlog skipped after a restore. The quit guard prompts
when the quit would stop the node and it is rebuilding, or has been
alive but only timing out / refusing as busy for >= 30 s. A replay alone
never prompts: stopping it is safe. The stop loop uses the same signal
to never offer Kill during a rebuild.

Also:
- daemon output offsets are absolute, so a reader that falls behind a
  trim of the 1 MB buffer no longer skips new output (which could hide a
  start or end marker)
- a quit deferred while minimized restores and raises the window, and
  the wizard renders the prompt, so it is never waiting unseen

Verified live with the fake daemon: quitting mid-rebuild now shows the
prompt for a v1.3.0 node and leaves the node alone; a silent busy node
prompts after 30 s.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 00:02:27 -05:00