Repository navigation
fix(mcp): stop waiting on a daemon record overwritten by a pre-1.0 daemon - #363
Merged
StefanSteiner merged 1 commit intoOct 21, 2026
Conversation
…emon A pre-1.0 daemon takes no daemon lock and rewrites daemon.json in its own shape. While a current daemon held the lock, clients saw a held lock beside an unreadable record, assumed the daemon was still starting, and polled the full 20 s spawn timeout. The local-mode fallback then failed to attach the persistent database (the daemon's hyperd already held it), so each engine retry repeated the wait and startup took about a minute. When the lock is held and the record is a legacy one, ask the lock holder for its own info over the endpoint the state directory implies and use that. If it does not answer within a 2 s grace, fail at once with an error naming the pre-1.0 daemon's pid and the file to delete.
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.
Summary
~/.hyperdb/daemon.jsonin its own shape (health_port, nohealth_endpoint). When it started while a current daemon held the lock, every client saw a held lock beside an unreadable record, concluded the daemon was still starting, and polled the full 20 sSPAWN_TIMEOUT.hyperdalready held it, error 55006), so each engine retry (warm_up_engine, then the first tool calls) repeated the wait. Observed startup: about 60 s (three consecutive 20 s waits inhyperdb-mcp.log, 4,900daemon discovery file is malformedlines).ensure_daemon_in, when the lock is held and the record is a legacy one, the client now asks the lock holder for its ownDaemonInfo(identifiedPING, thenSTATUS, on the endpoint the state directory implies) and uses it, going through the existing version-takeover check. If the holder does not answer within a 2 s grace (covers a daemon that has the lock but has not bound its endpoint yet) it fails immediately with an error naming the legacy daemon's pid and the file to delete. The legacy record is never removed here, since it belongs to a daemon that is still running.Test plan
held_lock_with_a_legacy_record_fails_fast_without_spawning(red before the fix: waited the full 30 s timeout)held_lock_with_a_legacy_record_recovers_the_info_from_the_lock_holder(unix; realHealthListeneron the well-known endpoint; red before the fix)cargo test -p hyperdb-mcp --lib daemon::: 88 passed, 0 failedcargo clippy --workspace --all-targets --all-features -- -D warningscleanRUSTDOCFLAGS="-D warnings" cargo doc --no-deps -p hyperdb-mcpcleancargo fmt --all,npx markdownlint-cli2clean on the changelogcfg(unix))Per-crate
hyperdb-mcp/CHANGELOG.mdupdated under[Unreleased]→### Fixed.