DB2: Tokio Mini Redis — Server (Part 1)
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 dereferencingOption<T>
instead of verbosematch
.
from_args
: Loads struct (here Cli struct) from command line arguments.
unwrap_or()
: orElse in Java Optional.
signal::ctrl_c()
: Shutdown event + TcpListener passed into the Server.
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
- 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 👏.