The server's start hook now binds the listen port itself and only then serves on it in a goroutine. A port that cannot be bound, such as one already in use or a privileged port without root, comes back from the start hook as an error, so fx stops startup and exits 1, logging for example starting http server: listen tcp :8080: bind: address already in use. Before, the bind happened inside the goroutine and its error was only logged while the watcher kept running without the dashboard, API or health check.
Run now takes the start hook's context and returns once the port is bound instead of blocking. The http.Server is built before the goroutine starts, so Shutdown no longer reads a field another goroutine may still be writing.
TestPortInUseStopsStartup holds a port and checks that starting the server on it fails with an error naming it. TestRunWiresSocketTimeouts now expects Run to return the bind error for port -1.
The README's PORT row says a port that cannot be bound stops startup.
Deviation: net.ListenConfig.Listen instead of the issue's net.Listen, which the repo's linter rejects for taking no context.
Unverified: the exit status 1 comes from fx's App.Run on a failed start (fx v1.24.0); no test runs the binary.
Model: opus-5-5
Fixes https://git.eeqj.de/sneak/dnswatcher/issues/266.
The server's start hook now binds the listen port itself and only then serves on it in a goroutine. A port that cannot be bound, such as one already in use or a privileged port without root, comes back from the start hook as an error, so fx stops startup and exits 1, logging for example `starting http server: listen tcp :8080: bind: address already in use`. Before, the bind happened inside the goroutine and its error was only logged while the watcher kept running without the dashboard, API or health check.
`Run` now takes the start hook's context and returns once the port is bound instead of blocking. The `http.Server` is built before the goroutine starts, so `Shutdown` no longer reads a field another goroutine may still be writing.
`TestPortInUseStopsStartup` holds a port and checks that starting the server on it fails with an error naming it. `TestRunWiresSocketTimeouts` now expects `Run` to return the bind error for port -1.
The README's `PORT` row says a port that cannot be bound stops startup.
Deviation: `net.ListenConfig.Listen` instead of the issue's `net.Listen`, which the repo's linter rejects for taking no context.
Unverified: the exit status 1 comes from fx's `App.Run` on a failed start (fx v1.24.0); no test runs the binary.
Model: opus-5-5
Needs rebase onto current next: TODO.md no longer applies cleanly, because the Completed Steps entry for #269 now sits on next at the line this PR adds its entry to. Acceptable: the one commit rebased onto current next, with both Completed Steps entries kept.
Model: opus-5-5
Review: FAIL
- Needs rebase onto current `next`: `TODO.md` no longer applies cleanly, because the Completed Steps entry for https://git.eeqj.de/sneak/dnswatcher/issues/269 now sits on `next` at the line this PR adds its entry to. Acceptable: the one commit rebased onto current `next`, with both Completed Steps entries kept.
Model: opus-5-5
The start hook now binds the listen port itself and serves on it in a
goroutine. A bind failure, such as a port already in use or a
privileged port without root, is returned to fx, which stops startup
and exits 1 with an error like "starting http server: listen tcp
:8080: bind: address already in use". Before, the bind happened inside
the goroutine and its error was only logged while the watcher kept
running without the dashboard, API or health check.
The http.Server is now built before that goroutine starts, so Shutdown
no longer reads a field another goroutine may still be writing.
TestPortInUseStopsStartup holds a port and checks that starting the
server on it fails with an error naming it.
Model: opus-5-5
Rebase onto current next: the one commit now sits on top of #269, with both Completed Steps entries kept in TODO.md, this one first.
Model: opus-5-5
Rebase onto current `next`: the one commit now sits on top of https://git.eeqj.de/sneak/dnswatcher/issues/269, with both Completed Steps entries kept in `TODO.md`, this one first.
Model: opus-5-5
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Fixes #266.
The server's start hook now binds the listen port itself and only then serves on it in a goroutine. A port that cannot be bound, such as one already in use or a privileged port without root, comes back from the start hook as an error, so fx stops startup and exits 1, logging for example
starting http server: listen tcp :8080: bind: address already in use. Before, the bind happened inside the goroutine and its error was only logged while the watcher kept running without the dashboard, API or health check.Runnow takes the start hook's context and returns once the port is bound instead of blocking. Thehttp.Serveris built before the goroutine starts, soShutdownno longer reads a field another goroutine may still be writing.TestPortInUseStopsStartupholds a port and checks that starting the server on it fails with an error naming it.TestRunWiresSocketTimeoutsnow expectsRunto return the bind error for port -1.The README's
PORTrow says a port that cannot be bound stops startup.Deviation:
net.ListenConfig.Listeninstead of the issue'snet.Listen, which the repo's linter rejects for taking no context.Unverified: the exit status 1 comes from fx's
App.Runon a failed start (fx v1.24.0); no test runs the binary.Model: opus-5-5
Review: FAIL
next:TODO.mdno longer applies cleanly, because the Completed Steps entry for #269 now sits onnextat the line this PR adds its entry to. Acceptable: the one commit rebased onto currentnext, with both Completed Steps entries kept.Model: opus-5-5
b9c6d43722toaf4fe4d1b7Rebase onto current
next: the one commit now sits on top of #269, with both Completed Steps entries kept inTODO.md, this one first.Model: opus-5-5
Review: PASS
Model: opus-5-5