fix(worker): dial control.json's bindAddress instead of hardcoding loopback - #30
Open
Eyalm321 wants to merge 1 commit into
Open
fix(worker): dial control.json's bindAddress instead of hardcoding loopback#30Eyalm321 wants to merge 1 commit into
Eyalm321 wants to merge 1 commit into
Conversation
…opback `worker.rs` built its base URL as `http://127.0.0.1:{port}`, ignoring `control.json`'s `bindAddress`. When the app binds a specific address (the mobile-client remote-access path) that is a single-socket bind, so loopback is not listening: every `POST /queues/<q>/claim` fails with ConnectionRefused and the worker exits before claiming any task. The failure is near-silent from the outside. Worker panes sit `running`/`idle` and tasks stay `queued` with `claimedBy: null`, which reads as an empty queue or a bad fan-out rather than a config fault — you only see it by reading a worker pane's tail. Observed against a tailnet bind, where it made every queue fan-out in the goals system drain nothing. `control_cli::base_url` already encodes the right rule and is reused here rather than duplicated: dial a specific address directly (bracketing IPv6), keep loopback for an unspecified (`0.0.0.0`/`::`) or absent bind, so legacy control.json files are byte-for-byte unaffected. The expression lives in `control_base()` so the tests exercise the same path `run()` does — reverting it to a hardcoded loopback turns them red, which a test that rebuilt the expression itself would not. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
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.
The bug
worker.rsbuilt its control-API base URL ashttp://127.0.0.1:{port}, ignoringcontrol.json'sbindAddress:When the app binds a specific address (the mobile-client remote-access path) that is a
single-socket bind, so loopback is not listening. Every
POST /queues/<q>/claimfails withConnectionRefusedand the worker exits before claiming anything.Why it is worth fixing rather than working around
The failure is near-silent from the outside. Worker panes sit
running/idleand tasks stayqueuedwithclaimedBy: null— which reads as an empty queue or a botched fan-out, not a configfault. The only tell is a worker pane's tail:
Observed against a tailnet bind, where it made every queue fan-out in the goals system drain
nothing. It was diagnosed only after mistaking it for bad task payloads.
The fix
control_cli::base_urlalready encodes exactly the right rule, so it is reused rather thanduplicated: dial a specific address directly (bracketing IPv6), keep loopback for an unspecified
(
0.0.0.0/::) or absent bind.bindAddressis#[serde(default)], so legacycontrol.jsonfiles are byte-for-byte unaffected.
Tests
Three tests in
worker::tests, driven from realcontrol.jsonpayloads:http://100.120.216.17:41419http://[fd7a::1]:41419(bracketed)0.0.0.0and::→http://127.0.0.1:41419The expression lives in a
control_base()helper so the tests call the same pathrun()does.Verified by mutation: reverting
control_baseto the hardcoded loopback turns the twospecific-address tests red (17 passed / 2 failed), and restoring it returns 19/19. A test that
rebuilt the expression itself would have passed either way — that earlier draft is what prompted
the refactor.
Full app-crate suite green: 160 + 2 passed, 0 failed.
worker.rsis rustfmt-clean (several otherfiles in the crate have pre-existing fmt diffs; untouched).
Not covered here
The npm MCP bridge (
hyperpanes-mcp,dist/control/discovery.js) has the identical defect — italso builds
http://127.0.0.1:<port>and dropsbindAddress, somcp__hyperpanes__*tools failthe same way. That lives outside this repo.