Skip to main content

Request Lifecycle

This page describes the current request path shared by the native QUIC and bootstrap ingress adapters. It focuses on decision ownership rather than wire or source-level detail.

Flow​

Route and backend resolution happen before route-scoped policy evaluation so Impulse knows which upstream policy, pool, and bounded observability identity apply. A locally rejected request does not proceed to backend dispatch; any selection accounting is finalized by the outcome path.

Ownership at a Glance​

ConcernOwnerBoundary
Downstream parsing and wire validationimpulse-edge::quic_listener native or bootstrap adapterProduces normalized method, path, authority, headers, body mode, peer identity, and timing context
Shared protocol limits and body guardrailsimpulse-edge::runtime::connection and resilience policyReturns typed allow, reject, timeout, and size-limit decisions; adapters serialize them
Route resolutionimpulse-edge::request_pipeline over edge::routingMatches method, path, and authority to one upstream
Backend selectionEdge forwarding service using impulse-lb poolsSelects an eligible backend and starts per-pool accounting
Admission and authenticationquic_listener::admission, edge::resilience, and shared request-policy servicesEvaluates local auth, rate limits, brownout, external auth, quota, and inflight protection in their defined phases
Request construction and response normalizationimpulse-bridgeApplies host/forwarded-header policy and hides protocol-specific H1/H2 request builders
Retry and hedge orchestrationimpulse-edge forwardingDecides whether another attempt is allowed and selects an alternate backend
Backend protocol executionimpulse-transportExecutes the chosen backend as HTTP/1.1 or HTTP/2 behind one façade
Terminal outcome and backend feedbackimpulse-edge::runtime::connection::outcome with adapter observation glueRecords canonical route/backend results and applies typed lifecycle feedback

1. Ingress Intake and Validation​

The native adapter owns UDP, QUIC/TLS, HTTP/3 connection and stream state. The bootstrap adapter owns TCP/TLS, HTTP/1.1 or HTTP/2 request intake, and HTTP/1.1-specific upgrade detection.

Each adapter validates its wire contract and produces the HTTP semantics needed by shared services. Connection, stream, and Hyper objects remain adapter-local; they are not shared request-policy types.

2. Route Resolution and Backend Selection​

The shared route service matches the validated method, path, and authority against the active generation's route index. It returns the upstream identity and match metadata. Edge forwarding then asks the upstream pool to select an eligible backend using the configured balancing strategy and request-key input.

impulse-lb owns algorithms, eligibility flags, and pool accounting. It does not own request parsing, routing precedence, auth, or transport execution.

3. Selected Policy and Admission​

The chosen upstream supplies the request policy. Pre-auth admission evaluates local API-key and JSON Web Token (JWT) policy, brownout, and scoped rate limiting. External authorization runs next when configured. Post-auth admission applies quota, route/global/upstream/backend inflight protection, queueing, circuit state, and adaptive admission as applicable.

Admission services return typed decisions. Native and bootstrap adapters retain only response serialization and protocol lifecycle duties; they should not invent different policy semantics.

4. Canonical Upstream Request​

After admission, impulse-bridge builds the upstream request for the selected backend transport. It owns:

  • host-policy and forwarded-header application
  • auth-approved header mutations
  • hop-by-hop request-header filtering
  • body-mode shaping
  • HTTP/1.1 upgrade request shaping
  • the internal H1 and H2 request builders

Edge supplies the normalized request, selected endpoint, and resolved policy; it does not duplicate header construction.

5. Dispatch, Retry, and Hedge​

Edge owns per-attempt orchestration: inflight permits, circuit state, retry budget, hedge eligibility, alternate selection, and request deadlines. Each attempt is handed to UpstreamTransportPool as a backend identity plus a canonical request.

Transport applies its connection and execution behavior and returns a canonical response or error. Shared classification maps that result to retryability, health feedback, and stable observability reasons; transport does not decide request policy.

6. Response and Streaming​

impulse-bridge::response filters hop-by-hop headers and trailers and decides bodyless/no-content emission policy. Shared connection guardrails enforce body size, prebuffer, idle, and total-streaming limits.

The adapters then diverge only for writeback:

  • native QUIC emits headers, chunks, trailers, and terminal state on the H3 stream
  • bootstrap returns an HTTP/1.1 or HTTP/2 response and handles an accepted HTTP/1.1 upgrade tunnel where applicable

7. Outcome Recording​

Every terminal path—success, upstream failure, timeout, local rejection, overload, client disconnect, or response abort—must finalize through shared outcome semantics. The outcome layer owns route/backend metrics, pool request accounting, passive health feedback, retry/hedge telemetry, and canonical reason mapping.

Adapters provide protocol-specific facts but must not independently redefine what the terminal result means.

Invariants​

  • Equivalent native and bootstrap requests receive the same route and policy decision unless the downstream protocol itself requires different behavior.
  • A route resolves to an upstream before that upstream's policy is evaluated.
  • Backend selection and transport execution remain separate decisions.
  • Only explicit http:// backends use upstream HTTP/1.1; HTTPS and schemeless backends use upstream HTTP/2 over TLS.
  • Every terminal path records an outcome once and releases its accounting and admission state.