Skip to content

feat(drr): implement Deterministic Request Replay engine and CLI tooling - #24

Open
insanerx wants to merge 4 commits into
mainfrom
feat/deterministic-request-replay
Open

insanerx wants to merge 4 commits into
mainfrom
feat/deterministic-request-replay

Conversation

@insanerx

@insanerx insanerx commented Sep 6, 2026

Copy link
Copy Markdown
Contributor

High-Level Overview

This PR introduces Deterministic Request Replay (DRR), a native zero-overhead request snapshotting and forensic debugging ecosystem for Volten. When enabled, DRR buffers incoming request payloads and captures full request metadata upon unhandled application crashes or exceptions. Snapshots are stored in a compact, compressed binary format (.vltn) that can be deterministically replayed against a target application instance for local debugging, automated regression testing, or forensic analysis.

The feature includes a hybrid in-memory/disk-spooling engine (HybridSpooler) to handle large body payloads without exploding memory usage, a middleware tracing framework (tracer.ts) for state-mutation diffing across middleware execution, and a dedicated CLI tool (volten drr) with terminal rendering for forensic inspection of crash snapshots.

Key Technical Changes

  • Core Engine Integration & Plugin Hooking (src/core/server.ts, src/utils/requestCtx.ts, src/utils/bodyParser.ts):

    • Added enableDrr() to App to attach a DRRPlugin instance and handle user-defined snapshot configurations.
    • Integrated crash interceptor in App.prototype.handleError to invoke drrEngine.onCrash() when unhandled errors bubble up.
    • Added drrEngine.tee() calls inside stream collectors (parseBody, parseMultipartStream) to capture incoming body buffer chunks non-intrusively during normal request processing.
    • Added drrEngine.onReset() in RequestContext.reset() to recycle and clean up spooler resources when contexts return to object pools.
  • Hybrid Spooler & Snapshot Compression (src/tools/drr/spooler.ts, src/tools/drr/index.ts):

    • Implemented HybridSpooler using a 64KB in-memory fast path; automatically spills over to OS temporary files (0o600 permissions on non-Windows) if body payload exceeds 64KB up to maxBodySize.
    • Implemented gzip compression and custom binary format for .vltn snapshot files ([4-byte big-endian metadata length][JSON metadata][payload body]).
    • Provided background cleanup (HybridSpooler.sweep()) to prune orphaned temporary spool files older than 1 hour.
  • Replay Engine & Middleware Tracing (src/tools/drr/replay.ts, src/tools/drr/tracer.ts, src/core/compose.ts):

    • Created replaySnapshot() which decompresses .vltn files, reconstructs mock Node IncomingMessage and ServerResponse streams, sets process.env.VOLTEN_DRR_REPLAY = "1", and re-dispatches through App.handleRequest.
    • Added traceMiddleware() in compose.ts (evaluated when VOLTEN_DRR_REPLAY === "1") to record middleware execution durations, caught errors, and context state mutation diffs (diffState()).
  • Forensic CLI Tooling (src/cli/index.ts, src/cli/renderer.ts, src/app.ts):

    • Added CLI command handler volten drr replay <file.vltn> and volten drr inspect <file.vltn> to display interactive terminal UI output including state mutations, timeline graphs, and stack traces.
  • Build & Test Suite (tsup.config.ts, tests/tools/drr.test.ts, tests/cli/drr-forensic.test.ts):

    • Added build entries for src/tools/drr/index.ts and src/tools/drr/replay.ts.
    • Added 20+ unit and forensic integration tests covering payload teeing, disk spillover, hooks (beforeSnapshot, onSnapshot), replay tracing, and CLI rendering.

Breaking Changes

None.

Adds the core implementation for DRR including spooler, tracer, and replay utilities.
Hooks into middleware compose, request context, and body parser to tee chunks and trace execution for DRR.
Provides a CLI to replay crash snapshots against the server. Updates build config and demo app.
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