Getting Started
Quickstart
A distributed counter running end to end in a few lines.
This walks through a complete program: connect to Redis, create a counter, and read it back. It uses only the default features, so a plain distkit = "0.5" is enough.
The whole thing
use distkit::{DistkitRedisKey, counter::{StrictCounter, LaxCounter, CounterOptions, CounterTrait}};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = redis::Client::open("redis://127.0.0.1/")?;
let conn = client.get_connection_manager().await?;
let prefix = DistkitRedisKey::try_from("my_app".to_string())?;
let options = CounterOptions::new(prefix, conn);
let key = DistkitRedisKey::try_from("page_views".to_string())?;
// Strict: every call is atomic and immediately consistent.
let strict = StrictCounter::new(options.clone());
strict.inc(&key, 1).await?;
let total = strict.get(&key).await?;
println!("strict: {total}");
// Lax: buffered locally, flushed on an interval - much faster on the hot path.
let lax = LaxCounter::new(options);
lax.inc(&key, 1).await?;
let approx = lax.get(&key).await?;
println!("lax: {approx}");
Ok(())
}
What happened
- Connect. A
ConnectionManageris built once and moved intoCounterOptions. It is clonable, sooptions.clone()lets the strict and lax counters share it. - Construct.
StrictCounter::newandLaxCounter::newboth returnArc<Self>, ready to share across tasks. - Use.
inc,get, and the rest come from theCounterTrait, which both counters implement.
Notice the CounterTrait import - methods like inc and get live on the trait, so it has to be in scope.
Where to go next
- Strict vs lax - the consistency trade-off you just chose between.
- Counters - the full counter API.
- Locks and instance-aware counters - the other primitives.

