Skip to content

perf: channel-based I/O driver for client (upload fix) #116

Description

@Yanstart

Context

Design: docs/plans/2026-03-19-channel-based-io-driver-design.md — Phase 1/3

Problem: After stages 1-4, upload stuck at ~8 Mbps on 95 Mbps baseline. stream_send() and poll task share the same Mutex. They serialize each other regardless of the event-driven backpressure changes.

Current: Download improved +135% (15 Mbps) and +232% (LEO 11.8 Mbps) but upload unaffected.

Solution

Replace Mutex with a channel-based I/O driver. Single tokio task owns quiche Connection exclusively. Relay tasks communicate via bounded mpsc channel (capacity 64 = 4MB).

Changes Required

crates/quick-transport/src/client.rs

  • Add SendCommand enum (StreamSend, StreamRecv, OpenStream, DgramSend, GetStats, Close)
  • Add run_io_driver() async function (select! loop: channel + socket + timer)
  • Add flush_packets() helper (batch collect + UDP send + BBR pacing)
  • Rewrite stream_send(): channel send + oneshot await (no Mutex)
  • Rewrite stream_recv(): channel send + oneshot await
  • Rewrite open_stream(), stats(), close(): same pattern
  • Make poll() a no-op
  • Remove connection: Arc<Mutex<Option<QuicConnection>>> field
  • Add send_tx: mpsc::Sender<SendCommand> field
  • Spawn I/O driver in connect() after handshake completes

bins/quick-entry/src/pool.rs

  • Remove start_background_tasks() manual poll loop (I/O driver replaces it)
  • Store I/O driver handles for shutdown

bins/quick-entry/src/main.rs

  • Remove manual poll loop (lines 772-805)
  • Health checks via periodic GetStats commands

Acceptance Criteria

  • QuicConnection owned exclusively by I/O driver (no shared Mutex)
  • stream_send() uses bounded mpsc channel (capacity 64)
  • Results returned via oneshot channels
  • poll() is a no-op
  • 351+ tests pass, CI green
  • Proxmox benchmark: terrestrial upload >30 Mbps (currently 8.27)
  • No memory leak under sustained load (bounded channel caps at 4MB)

Dependencies

Requires #110 (mutex split) merged — DONE.

Expected Impact

Upload: 8 Mbps → 50-80 Mbps terrestrial. GEO: 0 → 0.5+ Mbps.

Metadata

Metadata

Assignees

No one assigned

    Labels

    performanceThroughput and latency optimizations

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions