DB2: Tokio Mini Redis — Server (Part 1)

Arjun Sunil Kumar
Distributed Systems Engineering
4 min readApr 30, 2022

I am learning “how to read RUST”, more than “how to write RUST”. That said, let's look into mini-redis by tokio. Since it is a kind of a mini-project, let's understand things phase by phase. It is kind of an extended version of tiny-db, which we previously covered.

Project Structure:

/bin: contains the entry points (Driver ie Main Class) for binary server and client. The binary would compile the dependent classes.

/cmd: command pattern command classes. mod.rs is used for expositing it as a module in multi module architecture.

/lib.rs : Here we are creating this crate as a library

Let's start exploring files one by one, and understand this in detail.

README.md

Cargo.toml

Here

[[bin]]: signifies files that will be converted to binary. These driver files will compile all the dependent rust files and include them in the binary package. Remember, we used to have something called [[example]] as well.

dependencies:

tokio: runtime for async calls.

tracing: for logging in async.

tracing-subscriber: helper for tracing.

tokio-stream: for handling TCP connections

bin/server.rs

  • tracing_subscriber

tracing is a framework for instrumenting Rust programs to collect structured, event-based diagnostic information. tracing is maintained by the Tokio project, but does not require the tokio runtime to be used.

  • as_deref(): For dereferencing Option<T> instead of verbose match.
https://www.reddit.com/r/rust/comments/p0sb12/noob_needs_help_with_as_ref_and_as_deref/
  • from_args: Loads struct (here Cli struct) from command line arguments.
Cli struct for Server class
  • unwrap_or() : orElse in Java Optional.
  • signal::ctrl_c(): Shutdown event + TcpListener passed into the Server.
https://docs.rs/tokio/0.2.22/tokio/signal/fn.ctrl_c.html

src/server.rs

Contains:

Listener:

Server listener state. Created in the run call. It includes a run method which performs the TCP listening and initialization of per-connection state.

  • async fn run(&mut self) -> crate::Result<()>
  • async fn accept(&mut self) -> crate::Result<TcpStream>

Semaphore:

Broadcast: (AWS SNS)

A multi-producer, multi-consumer broadcast queue. Each sent value is seen by all consumers.

broadcast::Sender(): Sending-half of the broadcast channel.
May be used from many threads. Messages can be sent with send.

MSPS (AWS SQS)

A multi-producer, single-consumer queue for sending values between asynchronous tasks.
This module provides two variants of the channel: bounded and unbounded. The bounded variant has a limit on the number of messages that the channel can store, and if this limit is reached, trying to send another message will wait until a message is received from the channel. An unbounded channel has an infinite capacity, so the send method will always complete immediately. This makes the UnboundedSender usable from both synchronous and asynchronous code.

msps::Reciever: Receive values from the associated Sender.

msps::Sender: Send values to the associated Receiver.

TX and RX are abbreviations for Transmit and Receive, respectively. Note that these metrics are referenced to the server being monitored; Transmit FROM this server, and Receive TO this server.

Handler:

implements run() and Drop trait.

Per-connection handler. Reads requests from connection and applies the commands to db.

async fn run() for server

run() uses Listener to listen to the port and spin up Handler instances to serve the request.

src/lib.rs

pub mod is used to declare modules.

cmd/mod.rs

https://stackoverflow.com/questions/69140355/is-it-possible-to-avoid-using-mod-rs-files
  • pub fn from_frame(frame: Frame) : convert to Cmd from Frame.
  • pub(crate) async fn apply() : writes back response.
  • pub(crate) fn get_name(&self) : Returns command name

cmd/get.rs

Conclusion

Frame is a bit lengthy to cover today.

We will cover connection.rs,frame.rs, cli.rs , client.rs, db.rs, parse.rs etc in Part 2. We will cover buffer.rs,blocking_client.rs, shutdown.rs, ping, publish, subscribe in Part 3.

Found it Interesting?

Please show your support by 👏.

--

--

Arjun Sunil Kumar
Distributed Systems Engineering

Writes on Database Kernel, Distributed Systems, Cloud Technology, Data Engineering & SDE Paradigm. github.com/arjunsk