Skip to content

Dev server: survive rapid-save rebuild races and explain missing plugin state#14

Merged
shivamsn97 merged 1 commit into
mainfrom
fix/devserver-robustness
Jul 7, 2026
Merged

Dev server: survive rapid-save rebuild races and explain missing plugin state#14
shivamsn97 merged 1 commit into
mainfrom
fix/devserver-robustness

Conversation

@shivamsn97

Copy link
Copy Markdown
Member

Two development-server robustness fixes:

  1. A burst of rapid file saves can no longer kill the dev server. The incremental rebuild rewrote generated artifacts even when their content hadn't changed; Vite watches its own config, so a spurious rewrite of vite.config.js could trigger a config-restart that raced the next rebuild and left the process dead (nothing listening until a manual restart). Generated artifacts are now written only when content actually changes — atomically — and build passes are serialized. On top of that, the Vite subprocess is now supervised: an unexpected exit relaunches it with bounded exponential backoff (shutdown exits never relaunch), a relaunch that comes up but never starts listening is terminated rather than leaked, and if the budget is exhausted the failure surfaces as a clear structured error instead of a silent dead server.
  2. request.state.<name> errors now explain themselves. Using request.state.db in a loader or action without the providing plugin configured used to 500 with a bare AttributeError: 'State' object has no attribute 'db'. It's now a structured error explaining that state attributes are provided by plugins or middleware — naming pyxle-db for db — with the original traceback chained. Production responses stay generic; every other AttributeError flows through untouched.

Tests: 2202 passed, coverage 96.50%, including write-if-changed mtime stability, atomic-replace, 3-way build serialization, supervisor relaunch/shutdown/exhaustion/hung-child behaviors, and prod-response hygiene for both page and action paths.

…tate errors

- Generated build artifacts (meta.json; vite.config.js already guarded)
  are written only when content changes, atomically (temp + os.replace),
  and build passes are serialized — a burst of rapid saves no longer
  triggers spurious vite config-restarts that could race a rebuild and
  kill the dev server (HTTP 000 until manual restart).
- The vite subprocess is supervised: an unexpected exit relaunches with
  exponential backoff (bounded attempts, budget resets on a healthy
  relaunch), shutdown exits never relaunch, and exhaustion surfaces a
  structured ViteSupervisionError instead of a silent dead server. A
  relaunch that leaves vite running but never listening terminates the
  hung child on every failed attempt and on exhaustion — one fresh
  process per attempt, no orphans.
- request.state.<name> AttributeError in loaders/actions is re-raised
  as a structured error with plugin-config guidance (pyxle-db named for
  'db'), original traceback chained; production responses stay generic;
  other AttributeErrors flow through untouched.

Suite: 2202 passed, coverage 96.50%. Ruff clean.
@shivamsn97 shivamsn97 merged commit edd4fc7 into main Jul 7, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant