conductor crate

Status

Implemented (Tasks 1-3) — 2026-03-30

Purpose

Top-level builder API for railscale. Users call Conductor::tcp() or Conductor::sock() to construct a proxy pipeline without touching lower-level carriages/train_track types.

API

Conductor::tcp("0.0.0.0:8080")
    .route_tcp("127.0.0.1:3000")
    .replace_header(b"Host", b"localhost")
    .run().await
  • Conductor::tcp(addr)TcpBuilder
  • Conductor::sock(path)SockBuilder
  • Both builders share builder_methods! macro: route_tcp, route_sock, replace_header, record (metrics-full only)
  • TcpBuilder additionally has route_dynamic() — routes based on HTTP routing key
  • SockBuilder::run() panics if no route configured (no dynamic routing for unix sockets)

Internals

  • Config struct holds headers + route + optional record_path
  • Config::matchers() converts headers to Vec<(Finder<'static>, Bytes)>
  • Route enum: Tcp(String) | Sock(String) | Dynamic
  • Each run() constructs a train_track::Pipeline with appropriate source/router

Features

FeatureEffect
metrics-minimal (default)Enables OTel metrics in carriages/train_track
metrics-fullAdds recorder support (record() builder method, RecorderHandle)
metrics-erasedErased metrics variant

Files

  • conductor/Cargo.toml — deps: carriages, train_track (path), bytes/memchr/tracing/tokio (workspace)
  • conductor/src/lib.rs — entire implementation
  • conductor/src/router.rs — deleted (was empty leftover)

Gotchas

  • Finder::new() requires &[u8], not Vec<u8> — use &name not name.clone()
  • cargo can cache stale carriages lib.rs: if SockSource/TcpOverSockRouter appear missing despite being in source, touch carriages/src/lib.rs to invalidate
  • SockSource and TcpOverSockRouter were added to carriages/src/lib.rs in the same working-tree batch — they exist in working tree but not in the committed version (as of 2026-03-30)