fix(ui): pause host-proxy site when its dev-server worker is stopped (502 fix)#670
Merged
Merged
Conversation
Stopping a host-proxy site's "app" worker from the dashboard tore down only the dev-server unit and left the proxy vhost untouched. With the dev server gone, nginx kept proxying to the now-dead port and every request to the site returned 502 Bad Gateway. The "app" worker is synthesized (not a framework worker), so the worker:app:start path could not even restart it, leaving no symmetric way back. Route the parent app worker's start/stop through PauseSite/UnpauseSite, which swap the proxy vhost to the paused landing page (and back) and keep the registry's paused state consistent so the page's Resume button works. Other workers, worktree targets, and non-host-proxy sites keep the plain per-worker path. The routing decision is factored into hostProxyAppLifecycleOp with a table-driven test.
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.
Fixes #671.
Problem
Stopping a host-proxy site's dev server from the dashboard leaves the site returning 502 Bad Gateway for every request. Reproduced on a secured host-proxy site running a dev server (e.g.
pnpm dev): after stopping itsappworker the dev-server port is no longer listening, yet a request to the site returns502.The vhost is still the live proxy, pointing at the now-dead port:
Root cause
A host-proxy site's dev server is the synthesized
appworker (config.HostProxyWorkerName), not a framework worker. The dashboard'sworker:app:stopaction callsWorkerStopForSite, which tears down only thelerd-app-<site>unit. Nothing swaps the proxy vhost, so nginx keeps proxying to the dead port and 502s.It is also asymmetric: because
appis not in any framework'sWorkersmap, theworker:app:startpath bails with "worker app not defined", so once stopped there is no per-worker way to bring it back, onlylerd startor pause/unpause.PauseSitealready does the right thing for host-proxy sites (GeneratePausedVhostswaps the secured vhost to the paused page and removes the stale-ssl.conf, then reloads), andUnpauseSiterestores the proxy vhost and restarts the dev server. Stopping the only thing a host-proxy site runs is, semantically, pausing the site.Fix
Route the parent
appworker's start/stop throughPauseSite/UnpauseSiteat the dashboard handler (so there is no recursion throughWorkerStopForSite):worker:app:stop(parent, host-proxy) ->PauseSite: swaps the vhost to the paused landing page, stops the dev server, marks the site paused. The paused page's Resume button then works because the registry state is consistent.worker:app:start(parent, host-proxy) ->UnpauseSite: restores the proxy vhost and dev server.branchset), and non-host-proxy sites keep the plain per-worker path untouched.The decision is factored into a pure
hostProxyAppLifecycleOphelper so the routing is unit-testable without standing up the HTTP handler.Worktree host-proxy dev servers (
worker:app:stop?branch=...) have the same class of issue but no single-worktree pause primitive exists; left for a follow-up and explicitly excluded here (they keep the normal worker path).Test
TestHostProxyAppLifecycleOp(table-driven) pins the routing: parent app stop -> pause, start -> unpause, and untouched for non-host-proxy sites, other workers, worktree targets, and unknown ops.go build+go vet ./internal/uiclean.