mini-redis
- это неполная идиоматичная реализация клиента и сервера
Redis с помощью
Tokio.
Цель этого проекта - предоставить пример большого приложения, разработанного с помощью Tokio.
Дисклеймер Пожалуйста, не используйте mini-redis в продакшне. Этот проект является учебным ресурсом, в котором отсутствуют разные части протокола Redis, поскольку их реализация не представит новых концепций.
Основная цель этого проекта - изучение Tokio. Это требует проекта с широким набором возможностей с акцентом на простоте реализации. Redis, база данных, основанная на памяти, предоставляет широкий набор возможностей и использует простой сетевой протокол. Широкий набор возможностей позволяет продемонстрировать многие паттерны Tokio в контексте "реального мира".
Документацию сетевого протокола Redis можно найти здесь.
Набор команд, поддерживаемый Redis, можно найти здесь.
Репозиторий предоставляет сервер, клиентскую библиотеку и некоторые клиентские исполняемые файлы для взаимодействия с сервером.
Команда для запуска сервера:
RUST_LOG=debug cargo run --bin mini-redis-server
Для предоставления структурированных логов используется крейт tracing
.
Затем, в отдельном терминале, могут запускаться разные примеры клиентов, например:
cargo run --example hello_world
Кроме того, предоставляется клиент CLI для ручного запуска команд из терминала, например:
cargo run --bin mini-redis-cli set foo bar
cargo run --bin mini-redis-cli get foo
mini-redis
в настоящее время поддерживает следующие команды:
Спецификацию сетевого протокола Redis можно найти здесь.
Проект демонстрирует несколько полезных шаблонов, включая:
server.rs
запускает сервер TCP, который принимает соединения и создает новую задачу для каждого соединения. Он качественно обрабатывает ошибки accept
.
client.rs
показывает, как моделировать асинхронного клиента. Разные возможности предоставляются как async
методы.
Сервер поддерживает экземпляр Db
, который доступен всем соединениям. Экземпляр Db
управляет состоянием "ключ-значение", а также возможностью "издатель/подписчик".
connection.rs
и frame.rs
показывают идиоматичную реализацию сетевого протокола. Протокол моделируется с помощью промежуточного представления - структуры Frame
. Connection
принимает TcpStream
и предоставляет API для отправки и получения значений Frame
.
Сервер реализует мягкое завершение. tokio::signal
используется для регистрации SIGINT. После получения сигнала начинается завершение. Сервер перестает принимать соединения. Существующие соединения уведомляются о необходимости мягкого завершения. Выполняемая работа завершается и соединение закрывается.
Сервер использует Semaphore
для ограничения количества одновременных соединений. По достижении лимита сервер перестает принимать новые соединения до прекращения одного из существующих соединений.
Сервер реализует нетривиальную возможность "издатель/подписчик". Клиент может подписываться на несколько каналов и обновлять подписку в любое время. Сервер реализует это с помощью широковещательного канала и StreamMap
. Клиенты могут отправлять команды подписки на сервер для обновления активных подписок.
Сервер использует std::sync::Mutex
, а не мьютекс Tokio для синхронизации доступа к общему состоянию. См. db.rs
.
В tests/server.rs
находятся тесты для истечения времени жизни ключей. Эти тесты зависят от переданного времени. Для того, чтобы сделать тесты детерминистическими, используется фиктивное время с помощью утилит тестирования Tokio.
Этот проект находится под лицензией MIT.