# waymaker-client (Rust) Official Rust client for [waymaker](https://git.awesomike.com/dev/waymaker). ```toml [dependencies] waymaker-client = { git = "https://git.awesomike.com/pub/waymaker-client", tag = "v0.1.31" } # (the crate lives in the rust/ subdir; cargo resolves it automatically) ``` Proto stubs are generated from `../proto` at build time via `build.rs` — no dependency on the waymaker server workspace. ## Surfaces - `lock` — read/write locks, leader election, TTL leases. The `Lock` handle keeps a background task that **transparently re-binds** its event stream across a primary bounce (reusing the `request_id`) and exposes live state: `lock.fence_token()`, `lock.watch()` (a `watch::Receiver`), `lock.is_lost()`. `LockState::generation` distinguishes a same-generation re-bind from a fresh transparent acquire, while `LockState::renewal` exposes typed renewal success/failure and the authoritative renewed deadline. Pin the id/token/generation before protected work and reject any change. - `stream` — JetStream-lite publish + pull/push consumers. - `kv` — Put/Get/Create/Update(CAS)/Delete/Keys/History/Watch. - `cache` — Redis-shape Hash / Set / Queue (collections). - `probabilistic` — Bloom / HLL / CMS / TopK / t-digest. - `object` — chunked object Put/Get. Raw generated stubs are available under `server` / `streams_server` / `kv_server` / `collections_server` / `sketches_server` / `cache_server`. ## Leader election ```rust use std::time::Duration; use waymaker_client::{Client, lock}; let client = Client::connect("http://127.0.0.1:8818").await?; let lock = client.acquire_lock("leader:reports", lock::Config { max_wait: Duration::ZERO, // try-acquire lease_ttl: Duration::from_secs(30), scope: lock::Scope::Quorum, // Raft-replicated fence ..Default::default() }).await?; let _renewal = lock.spawn_renewal(Duration::from_secs(15)); // Pin one ownership generation; a transparent re-win cannot inherit work. let mut state = lock.watch(); let admitted = state.borrow().clone(); loop { let current = state.borrow().clone(); if current.lost || current.generation != admitted.generation || current.id != admitted.id || current.fence_token != admitted.fence_token || matches!(current.renewal, lock::RenewalState::Failed(_)) { break; } do_fenced_write(admitted.fence_token).await?; state.changed().await.ok(); } ```