Brief
You are building a Redis subset — server and client — on Tokio, speaking real RESP over
TCP, supporting GET/SET and pub/sub, shutting down gracefully. The official Tokio
tutorial is the guide; this subject states what each stage must deliver and how to prove
it, so the tutorial keeps the prose and you keep the checklist. Every line is yours: the
tutorial's code is reference, not a paste source.
Instructions
Work the stages in order; each leaves a binary that runs.
Stage 1 — Hello Tokio
Set up the runtime (#[tokio::main]), write your first async fn and .await, and use
the stock mini-redis client crate against the reference server to observe the target
behavior (SET/GET round trip) you are about to reimplement.
Stage 2 — Accept loop
A TcpListener accept loop that tokio::spawns a task per connection. Fight and win
the compiler argument about what may cross into a spawned task: move the socket in,
own your data, understand why the future must be Send + 'static. Serve a hardcoded
response to prove connections are handled concurrently.
Stage 3 — Shared state
A real GET/SET store: HashMap behind Arc<Mutex<…>> (std mutex), cloned into
every connection task. Rules to internalize and honor: the lock guard must not be
held across an .await (structure the code so it can't be); keep critical sections
short. Then shard the map (a vector of mutexed maps, keyed by hash) to cut contention.
Stage 4 — Framing
A Connection type that turns the byte stream into RESP frames and back: read into a
BytesMut cursor, attempt a frame parse, and treat frame-not-complete-yet as the normal
case that waits for more bytes — never an error. Handle partial reads and leftover bytes
after a frame. Write side goes through a BufWriter, flushed at frame boundaries.
Stage 5 — Channels (client side)
A client that multiplexes many callers over one connection: callers send commands to a
manager task through an mpsc channel, each carrying a oneshot sender for its reply;
the manager owns the connection and pairs responses to waiters. Message passing as the
alternative to locking the connection.
Stage 6 — Select & shutdown (plus pub/sub)
Implement SUBSCRIBE/PUBLISH so a client can wait on messages, then wire graceful
shutdown: select! over connection I/O and a shutdown broadcast channel; on
Ctrl-C, stop accepting, let in-flight connections drain, and observe
cancellation-by-drop doing its quiet work — a branch not taken in select! is a future
dropped mid-poll. Note one place where an unexpected cancellation point surprised you.
Constraints
- Rust with Tokio,
bytes, and themini-rediscrate only as the reference client/protocol types where the tutorial uses it — the server logic, connection handling, framing, and state are written by you. - No
unwrap()on I/O paths in the final version; connection errors terminate that connection, never the server. - The std-mutex rule stands: no lock guard alive across an
.await(clippy'sawait_holding_lockclean).
Acceptance
Mapped one-to-one onto the exercise's milestones:
- Hello Tokio — a
SET/GETround trip against the reference server runs from your async main; you can say what.awaityields to and what#[tokio::main]generates. - Accept loop — two simultaneous clients are served concurrently (verify with an
interleaved test); the spawned-task ownership error was hit and fixed via
move, not by cloning blindly. - Shared state — concurrent
SETs andGETs from many tasks are correct;await_holding_lockis clean; the sharded version passes the same tests and shows reduced contention under a parallel benchmark. - Framing — a frame delivered one byte at a time parses correctly (partial-read test); two frames in one read both parse; writes are buffered and flushed per frame.
- Channels — N concurrent callers through one multiplexed client each get their own
correct response, matched via their
oneshot; dropping a caller doesn't wedge the manager. - Select & shutdown — a subscriber receives published messages; Ctrl-C drains cleanly (no task leaks, listener closed, in-flight requests finish); the cancellation-surprise note exists.
Related
- Tokio mini-redis — the exercise this is the subject of.
- The Tokio tutorial — the guide carrying the prose for every stage above.
- Protohackers ladder — subject — the same network-server territory under Go's model.