Line-Protocol TCP Server (Rust)
Topics: TCP, line protocol, threads, graceful drain
Problem
Build a small scheme simulator: a TCP server speaking a newline-terminated request/response
protocol, with a graceful shutdown that drains in-flight work. (Inspired by the payment-scheme
simulators payment platforms build for testing — the protocol here is a generic task runner.)
pub struct Cancel(/* … */);
pub struct Server { /* … */ }
impl Server {
pub fn new(addr: &str, grace: Duration) -> Server;
pub fn run(&self, cancel: &Cancel) -> std::io::Result<()>;
pub fn addr(&self) -> String;
pub fn wait_started(&self, timeout: Duration) -> bool;
}
Protocol (one request in flight per connection, connections reused):
RUN|<ms>\n → after ~<ms> of simulated work, OK|done\n.
- Malformed (not
RUN|<int>) → ERR|invalid request\n.
<ms> not a non-negative integer → ERR|invalid amount\n.
Graceful shutdown (when cancel fires):
- Stop accepting new connections.
- Give in-flight requests up to
grace to finish.
- A request still running when
grace expires → ERR|cancelled\n.
run returns once in-flight work has drained.
Key concepts
- Per-connection thread reading newline-framed requests via
BufRead::read_line; one request is
answered before the next is read.
- Drain accounting: a
Drain holding an in-flight count (Mutex + Condvar) and a hard
AtomicBool. On shutdown the accept loop stops, waits for the count to reach zero up to grace,
then sets hard so long-running work bails out with cancelled.
- Scope: slow/half-open clients are out of scope — only clean termination by client or server.
Cancel, Server::{new, addr, wait_started}, Drain, and parse are provided; you implement
run and the connection handling.
Grading
Your solution.rs is compiled together with a trusted tests.rs (which include!s it) using
rustc --test. Only solution.rs is yours to edit.
Sign in to submit your solution.