Ft/instance aware counter#10
Conversation
Review Summary by QodoAdd instance-aware counters with per-instance tracking and automatic dead-instance cleanup
WalkthroughsDescription• **Instance-aware counters**: Introduces two new counter types (StrictInstanceAwareCounter and LaxInstanceAwareCounter) that track per-instance contributions separately with automatic dead-instance cleanup via epoch-based mechanisms and Lua scripts • **Strict instance-aware counter**: Fully consistent counter with immediate atomic operations, background heartbeat task for dead-instance detection, and recovery logic via pipelined INC_IF_EPOCH_MATCHES_LUA calls • **Lax instance-aware counter**: Eventually-consistent counter that buffers inc/dec deltas locally and flushes them in batches (default 20 ms) to the backing strict counter • **Shared trait**: New InstanceAwareCounterTrait with 10 async methods (instance_id, inc, dec, set, set_on_instance, get, del, del_on_instance, clear, clear_on_instance) • **Activity tracking utility**: New ActivityTracker for coordinating background flush task sleep/wake cycles, replacing custom epoch-change logic in LaxCounter • **Breaking changes**: Removed Counter facade; StrictCounter and LaxCounter now constructed directly from CounterOptions; StrictCounter::new() now returns Arc<StrictCounter> • **Comprehensive documentation**: Rewritten README.md and docs/lib.md with unified 4-column comparison table, full usage examples for all counter types, and 57 executable doc tests • **Test coverage**: 115 unit tests for instance-aware counters plus 57 doc tests (172 total), covering single/multi-instance scenarios, epoch propagation, dead-instance cleanup, and recovery logic • **Infrastructure**: Added GitHub Actions CI workflow with Redis service, updated Makefile with Docker Compose targets, added instance-aware-counter feature flag (enabled by default), and uuid dependency Diagramflowchart LR
A["CounterOptions"] -->|"new()"| B["StrictCounter<br/>Arc wrapped"]
A -->|"new()"| C["LaxCounter<br/>buffered deltas"]
A -->|"new()"| D["StrictInstanceAwareCounter<br/>per-instance tracking"]
A -->|"new()"| E["LaxInstanceAwareCounter<br/>buffered + per-instance"]
D -->|"implements"| F["InstanceAwareCounterTrait"]
E -->|"implements"| F
D -->|"uses"| G["Lua scripts<br/>epoch-safe ops"]
D -->|"uses"| H["Heartbeat task<br/>dead-instance cleanup"]
E -->|"flushes to"| D
E -->|"uses"| I["ActivityTracker<br/>flush coordination"]
C -->|"uses"| I
File Changes1. src/icounter/strict_instance_aware_counter.rs
|
Branch Changes
New Features
Instance-Aware Counters (
icountermodule)A fully new counter family that tracks each running instance's contribution separately, with automatic cleanup of dead instances.
StrictInstanceAwareCounter— immediately consistent; everyinc,set,get,del, andclearexecutes atomically against Redis via Lua scripts. Tracks per-instance counts in a Redis hash, uses an epoch-based mechanism to detect stale contributions, and runs a background heartbeat task to keep the instance registered as live. Dead instances (no heartbeat fordead_instance_threshold_ms, default 30 s) are automatically removed from the cumulative total by the next live instance that touches the same key.LaxInstanceAwareCounter— eventual consistency;inc/decdeltas are buffered locally and flushed in batches to the backingStrictInstanceAwareCountereveryflush_interval(default 20 ms). Epoch-bumping operations (set,del,clear) flush any pending delta first, then delegate immediately to the strict counter.InstanceAwareCounterTrait— shared async interface with 10 methods:instance_id,inc,dec,set,set_on_instance,get,del,del_on_instance,clear,clear_on_instance.ActivityTracker— internal utility that tracks whether a counter is actively being used, allowing background tasks (heartbeat, flush) to sleep when idle and wake immediately on activity.Recovery logic — when
StrictInstanceAwareCounter's heartbeat detects its instance was cleaned up as dead while offline (e.g. GC pause or network blip), it recovers its contributions epoch-safely via pipelinedINC_IF_EPOCH_MATCHESLua calls.Breaking Changes
Counterfacade removedThe
Counterenum/facade has been deleted.StrictCounterandLaxCounterare now created directly fromCounterOptions:CounterOptionsnow implementsClone.decadded toInstanceAwareCounterTraitAll instance-aware counter implementations expose a
decmethod that delegates toinc(key, -count).StrictCounter::newreturnsArc<StrictCounter>Previously returned a plain value.
Documentation
README.md and
docs/lib.mdrewritten: updated quick-start examples, unified 4-column comparison table covering all four counter types (StrictCounter, LaxCounter, StrictInstanceAwareCounter, LaxInstanceAwareCounter), and full usage examples for both instance-aware counter types includingdec.Inline
# Examplesadded to every public method on all four counter types andInstanceAwareCounterTrait— 57 doc tests total, all executed (notno_run) against a real Redis instance.src/__doctest_helpers.rs— a#[doc(hidden)]module providing shared async setup helpers (strict_counter,lax_counter,strict_icounter,two_strict_icounters,lax_icounter,two_lax_icounters). Each generates a UUID-namespaced Redis prefix so concurrent doc tests never share state. The Redis URL is read from$REDIS_URL, defaulting toredis://127.0.0.1:6379.Infrastructure
.github/workflows/workflow.yml) added.redis-up,redis-down,test, andbenchtargets backed by Docker Compose.instance-aware-counterfeature flag added toCargo.toml; enabled by default.