redis-server-wrapper
Type-safe Rust wrapper for redis-server and redis-cli with builder pattern APIs.
Manage Redis server processes for testing, development, and CI without Docker --
just redis-server and redis-cli on PATH.
Features
- Single server -- start/stop with builder pattern, auto-cleanup on drop
- Cluster -- spin up N-master clusters with optional replicas
- Sentinel -- full sentinel topology (master + replicas + sentinels)
- Custom binaries -- point to any
redis-server/redis-clipath - Arbitrary config -- pass any Redis directive via
.extra(key, value)
Prerequisites
redis-server and redis-cli must be available on your PATH (or specify custom paths with
.redis_server_bin() and .redis_cli_bin() on any builder).
Installation
Add to Cargo.toml for async use (the default):
[]
= "0.1"
The tokio feature is enabled by default. To use the synchronous blocking API instead,
disable default features and enable blocking:
[]
= { = "0.1", = false, = ["blocking"] }
To use both async and blocking APIs together:
[]
= { = "0.1", = ["blocking"] }
Usage
The async API requires tokio. See the Blocking API section for synchronous use.
Single Server
use RedisServer;
let server = new
.port
.bind
.start
.await
.unwrap;
assert!;
// Stopped automatically on drop.
The server process is stopped via SHUTDOWN NOSAVE when the handle is dropped.
Call server.detach() to consume the handle without stopping the process.
Configuration
Common options have dedicated builder methods. Anything else can be passed as
a raw Redis directive with .extra(key, value):
use ;
let server = new
.port
.bind
.password
.loglevel
.appendonly
.extra
.extra
.start
.await
.unwrap;
Running Commands
The handle exposes a RedisCli you can use to run arbitrary commands against the server:
use RedisServer;
let server = new.port.start.await.unwrap;
server.run.await.unwrap;
let val = server.run.await.unwrap;
assert_eq!;
You can also get a RedisCli instance directly from the handle:
use RedisServer;
let server = new.port.start.await.unwrap;
let cli = server.cli;
let pong = cli.ping.await;
assert!;
Cluster
use RedisCluster;
let cluster = builder
.masters
.replicas_per_master
.base_port
.start
.await
.unwrap;
assert!;
Sentinel
use RedisSentinel;
let sentinel = builder
.master_port
.replicas
.sentinels
.start
.await
.unwrap;
assert!;
Error Handling
All fallible operations return Result<T, Error>. The Error enum covers server
start failures, timeouts, CLI errors, and underlying I/O errors:
use ;
match new.port.start.await
Blocking API
Enable the blocking feature for synchronous wrappers that require no async runtime:
[]
= { = "0.1", = ["blocking"] }
The blocking module mirrors the async API. Every operation blocks the calling thread
until it completes. Handles own a long-lived tokio::runtime::Runtime so that the
underlying async Drop implementation keeps working correctly.
use RedisServer;
let server = new
.port
.bind
.start
.unwrap;
assert!;
// Stopped automatically on drop.
Use server.detach() in the blocking API for the same keep-running behavior.
Cluster and Sentinel work the same way:
use ;
let cluster = builder
.masters
.base_port
.start
.unwrap;
assert!;
let sentinel = builder
.master_port
.replicas
.sentinels
.start
.unwrap;
assert!;
Examples
The crate ships a runnable example that demonstrates various server configurations:
License
Licensed under either of
- Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)
at your option.