fix(config): derive core health URL from [core].port - #122
Conversation
genie-health and the genie-api dashboard Services row both sourced the core probe URL from [services.core].url, while genie-ctl and the genie-api TCP proxy (post-GeniePod#90 / GeniePod#102) derive it from [core].port via Config::core_http_addr(). When an operator changed only [core].port and left [services.core].url at its default, the probes hit the wrong port and showed core as DOWN even though it was healthy on the new port. - Add Config::core_health_url() in genie-common that returns "http://{core_http_addr()}/api/health". Single source of truth shared by every local core health probe. - genie-health: collect_endpoints() now returns (name, resolved_url) and uses core_health_url() for the core entry. LLM and optional services keep reading [services.<svc>].url so their existing override semantics are preserved. - genie-api: dashboard_service_targets() core entry uses core_health_url() for latency_url so the Services row tracks the configured port. - Tests: genie-common covers default/custom port, custom bind_host, and the listen-all-mapped-to-loopback case. genie-health and genie-api each have a regression test asserting the core URL follows [core].port when [services.core].url is left stale, plus a sibling test confirming LLM still sources from [services.llm].url. Fixes GeniePod#121.
|
Not merging this yet. After refreshing the branch against current main and approving the fork checks, Failure: This looks like the new |
ai-hpc
left a comment
There was a problem hiding this comment.
Requesting changes because the refreshed branch has a failing required test job: cargo test --workspace --locked --all-targets fails in checker::tests::llm_endpoint_url_still_sources_from_services_config with database is locked. Please isolate the new health-check tests from shared SQLite state or avoid opening a shared runtime DB in these endpoint assertions, then refresh against current main.
The three checker unit tests each constructed a HealthMonitor via HealthMonitor::new(test_config()) to reach collect_endpoints, which opens the SQLite log DB at config.data_dir. Under the parallel cargo test runner all three would race for the write lock on the shared /tmp/geniepod-health-test/health.db path, producing "database is locked" failures in CI (workspace test job). collect_endpoints only reads from &Config — it never touches self.db or self.failure_counts — so make it a module-level free function taking &Config. check_all calls it as collect_endpoints(&self.config); the three tests now call collect_endpoints(&test_config()) (or a mutated config) directly and never open the DB. Pure refactor: behavior of HealthMonitor is unchanged.
|
Reviewed and closed: this PR is conflicting with current main and already has requested changes, so it is not safe to merge as-is. Please reopen or resubmit a rebased branch if you want to continue it; thanks @Khaostica. |
|
Reviewed and superseded: #121 was valid, but this branch is conflicting and maintainer edits are disabled, so #122 could not be merged directly. Ported and merged the valid fix in #158 at 99650b1; thanks @Khaostica. |
Summary
genie-healthand thegenie-apidashboard Services row sourced the core probe URL from[services.core].url, whilegenie-ctland thegenie-apiTCP proxy (post-#90 / PR #102) derive it from[core].portviaConfig::core_http_addr(). When an operator changes only[core].portand leaves[services.core].urlat its default, the probes hit the wrong port and report core as DOWN even though it is healthy on the configured port.Fixes #121.
Changes
Config::core_health_url()ingenie-common— single source of truth for the local core health URL, derived from[core].portand[core].bind_host.genie-health::collect_endpoints()now returns resolved(name, url)pairs and usescore_health_url()for thecoreentry. LLM and the optional services keep sourcing from[services.<svc>].urlso their existing override semantics are unchanged.genie-api::dashboard_service_targets()core entry usescore_health_url()forlatency_url.[core].port = 3001with a stale default[services.core].urlon:3000must derive:3001.Behavior is unchanged when the default config is used (
port = 3000, default URL).Real Behavior Proof
What I ran
Windows dev box, no Jetson available, no cross-compile toolchain installed:
cargo fmt --all -- --check— cleancargo clippy -p genie-common --all-targets -- -D warnings— cleancargo test -p genie-common— 38 passed, 0 failed (5 new tests coveringcore_health_url(): default port, custom port, custombind_host, listen-all → loopback mapping, and the stale[services.core].urloverride case).genie-healthandgenie-apiuse Unix-only deps (std::os::unix, tokio signal handlers) and cannot compile on Windows — pre-existing constraint, not introduced by this PR. New regression tests added in each (core_endpoint_url_tracks_configured_core_portingenie-health;dashboard_core_target_uses_derived_health_urlingenie-api) will exercise on the Linux CI job.What I observed
cargo test -p genie-commonexcerpt:Reviewer with Jetson access: please apply the repro from the issue body (
[core] port = 3001, leave[services.core].urlat the:3000default) and confirmgenie-healthlogs and the dashboard Services row both report core healthy on the new port.Test plan
[core] port = 3001, leave default[services.core].url.GENIEPOD_CONFIG=...for genie-core, genie-health, genie-api.genie-ctl healthandgenie-healthlogs should agree — core healthy on:3001.port = 3000, default URL) and confirm no regression.Notes for reviewers
[services.core].urlis intentionally left in the config schema for backward compatibility. The issue body suggested logging a divergence warning atConfig::load(); deferred from this PR to keep scope tight on the bug fix — happy to follow up if you'd like it.[services.<svc>].url— onlycoreis special-cased because onlycorehas a dedicated[core]config block as the listen-side source of truth.