Files
mini-redis/README.md
Carl Lerche 757de6762d add readme and license (#30)
Co-authored-by: Alice Ryhl <alice@ryhl.io>
2020-04-13 15:26:54 -07:00

4.3 KiB

mini-redis

mini-redis is an incomplete, idiomatic implementation of a Redis client and server built with Tokio.

The intent of this project is to provide a larger example of writing a Tokio application.

Disclaimer Don't even think about trying to use this in production... just don't.

Running

The repository provides a server, client library, and some client executables for interacting with the server.

Start the server:

RUST_LOG=debug cargo run --bin server

The tracing crate is used to provide structured logs. You can substitute debug with the desired log level.

Then, in a different terminal window, the various client examples can be executed. For example:

cargo run --example hello_world

Additionally, a CLI client is provided to run arbitrary commands from the terminal. With the server running, the following works:

cargo run --bin cli set foo bar

cargo run --bin cli get foo

Supported commands

mini-redis currently supports the following commands.

The Redis wire protocol specification can be found here.

Tokio patterns

The project demonstrates a number of useful patterns, including:

TCP server

server.rs starts a TCP server that accepts connections, and spawns a new task per connection. It gracefully handles accept errors.

Client library

client.rs shows how to model an asynchronous client. The various capabilities are exposed as async methods.

State shared across sockets

The server maintains a Db instance that is accessible from all connected connections. The Db instance manages the key-value state as well as pub/sub capabilities.

Framing

connection.rs and frame.rs show how to idiomatically implement a wire protocol. The protocol is modeled using an intermediate representation, the Frame structure. Connection takes a TcpStream and exposes an API that sends and receives Frame values.

Graceful shutdown

The server implements graceful shutdown. tokio::signal is used to listen for a SIGINT. Once the signal is received, shutdown begins. The server stops accepting new connections. Existing connections are notified to shutdown gracefully. In-flight work is completed, and the connection is closed.

Concurrent connection limiting

The server uses a Semaphore limits the maximum number of concurrent connections. Once the limit is reached, the server stops accepting new connections until an existing one terminates.

Pub/Sub

The server implements non-trivial pub/sub capability. The client may subscribe to multiple channels and update its subscription at any time. The server implements this using one broadcast channel per channel and a StreamMap per connection. Clients are able to send subscription commands to the server to update the active subscriptions.

Contributing

Contributions to mini-redis are welcome. Keep in mind, the goal of the project is not to reach feature parity with real Redis, but to demonstrate asynchronous Rust patterns with Tokio.

Commands or other features should only be added if doing so is useful to demonstrate a new pattern.

Contributions should come with extensive comments targetted to new Tokio users.

FAQ

Should I use this in production?

No.

License

This project is licensed under the MIT license.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in mini-redis by you, shall be licensed as MIT, without any additional terms or conditions.