Railscale Connection Lifecycle
Deep-dive into Pipeline::do_connection() in train_track (train_track/src/core/service.rs).
Phase 1: Parse Until Routing Key
Client bytes -> FrameParser::parse() -> Stream<ParsedData>
Reads frames sequentially, buffering into pre_route_buf:
ParsedData::Passthrough(bytes)— raw bytes, buffered as-isParsedData::Parsed(frame)— processed throughFramePipeline::process(), theninto_bytes()
Breaks out of the loop when a frame returns Some from routing_key().
NoRoutingFrame
If the stream ends without producing a routing frame, returns
RailscaleError::NoRoutingFrame.
Phase 2: Concurrent Route + Parse
let (dest_result, post_route_buf) = tokio::join!(
router.route(&routing_key),
async { /* continue parsing remaining frames */ }
);Two things happen simultaneously:
DestinationRouter::route()resolves the routing key to a connected upstream (e.g., TCP connect)- Remaining frames continue parsing into
post_route_buf
This overlaps upstream connection latency with continued request parsing.
Phase 3: Forward + Relay
pre_route_buf -> dest.write() (sequential)
post_route_buf -> dest.write() (sequential)
dest.relay_response(&mut write_half) -> client
Flushes both buffers to the destination, then relays the upstream response back to the client’s write half.
Timing Breakdown
| Metric | What it measures |
|---|---|
forward_duration | Phase 1 + 2 + 3 (write) — total request forwarding |
connect_duration | Phase 2 — routing/upstream connect time |
relay_duration | Phase 3 (relay) — response piping time |
total_duration | Full connection lifetime |
OTel Metrics
| Metric | Type | When |
|---|---|---|
connections_total | Counter | conn_start |
connections_active | UpDownCounter | conn_start / conn_end |
connection_errors | Counter | on error |
connection_duration_seconds | Histogram | conn_end |
request_forward_duration_seconds | Histogram | forward_done |
upstream_connect_duration_seconds | Histogram | upstream_connected |
response_relay_duration_seconds | Histogram | relay_done |
response_bytes | Histogram | relay_done |
frames_parsed | Counter | forward_done |
bytes_passthrough | Counter | forward_done |