distkit
A toolkit of distributed systems primitives for Rust, backed by Redis.
What is distkit?
distkit provides building blocks for distributed applications. It ships distributed counters (strict and lax) and rate limiting, all backed by Redis.
Features
- StrictCounter -- every operation executes a Redis Lua script atomically. Reads always reflect the latest write. Best for billing, inventory, or anything where accuracy is critical.
- LaxCounter -- buffers increments in memory and flushes to Redis every ~20 ms. Sub-microsecond latency on the hot path. Best for analytics and high-throughput metrics.
- Shared trait -- both counters implement
CounterTrait, so generic code works with either. - Rate limiting (opt-in
trypemafeature) -- sliding-window rate limiting with local, Redis-backed, and hybrid providers. Supports absolute and probabilistic suppression strategies. - Safe by default --
#![forbid(unsafe_code)], no panics in library code.
Feature flags
| Feature | Default | Description |
|---|---|---|
counter |
yes | Distributed counters (StrictCounter, LaxCounter) |
trypema |
no | Rate limiting via the trypema crate |
Installation
Or add to Cargo.toml:
[]
= "0.1"
To enable rate limiting:
[]
= { = "0.1", = ["trypema"] }
distkit requires a running Redis instance (5.0+ for Lua script support).
Quick start
use ;
async
Counter types
StrictCounter
Every call is a single Redis round-trip executing an atomic Lua script. The counter value is always authoritative.
let key = try_from?;
counter.strict.inc.await?; // HINCRBY via Lua
counter.strict.set.await?; // HSET via Lua
counter.strict.del.await?; // HDEL, returns old value
counter.strict.clear.await?; // DEL on the hash
LaxCounter
Writes are buffered in a local DashMap and flushed to Redis in batched
pipelines every allowed_lag (default 20 ms). Reads return the local view
(remote_total + pending_delta), which is always consistent within the same
process.
let key = try_from?;
counter.lax.inc.await?; // local atomic add, sub-microsecond
let val = counter.lax.get.await?; // reads local state, no Redis hit
A background Tokio task handles flushing. It holds a Weak reference to the
counter, so it stops automatically when the counter is dropped.
Rate limiting (trypema)
Enable the trypema feature to access sliding-window rate limiting with three
provider options (local, Redis-backed, hybrid) and two strategies (absolute,
suppressed). All types from the trypema
crate are re-exported under distkit::trypema.
Trypema documentation website: https://trypema.davidoyinbo.com
use Arc;
use ;
let rl = new;
rl.run_cleanup_loop;
let rate = try_from.unwrap; // 10 req/s
match rl.local.absolute.inc
For distributed enforcement, enable the Redis provider and use
rl.redis() or rl.hybrid(). See the
trypema documentation for full details.
Development
Prerequisites
- Rust (latest stable)
- Docker (for the test Redis instance)
Commands
Tests and benchmarks require the REDIS_URL environment variable.
The make targets set this automatically.
License
MIT