-
Notifications
You must be signed in to change notification settings - Fork 0
Ft/v0.3.0 #13
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Ft/v0.3.0 #13
Changes from all commits
Commits
Show all changes
41 commits
Select commit
Hold shift + click to select a range
0ee4d36
feat: additional tests for lax counters
dev-davexoyinbo 8871534
test: test for different scenario
dev-davexoyinbo cbca476
test: add test to to test staleness
dev-davexoyinbo edf68ee
fix: fix fetching stale
dev-davexoyinbo 0bcabcf
fix: race condition happening because of reset of the flush all_keys
dev-davexoyinbo f3463b4
feat: execute_pipeleine_with_script_retry
dev-davexoyinbo b431b73
fix: fix race condition for flushes
dev-davexoyinbo 8a0fb0c
feat: interface for set_all and get_alls
dev-davexoyinbo de82903
feat: get_all and set_all implementations for lax_counter
dev-davexoyinbo 9cc050c
feat: get_all and set_all implementation for strict_counter
dev-davexoyinbo 9f40768
feat: use as_str instead of to_string
dev-davexoyinbo a9415b3
feat: use max batch size const
dev-davexoyinbo eabebab
feat: get_batch on strict instance aware
dev-davexoyinbo 445533c
feat: include key in the get
dev-davexoyinbo bf713c3
feat: get and get_all
dev-davexoyinbo e3b7b47
feat: set all and set all on instance
dev-davexoyinbo 2ce7f2c
feat: batch refresh stale
dev-davexoyinbo 8cff052
feat: get_all lax_instance aware
dev-davexoyinbo 43403fd
fix get_all_on instance , add locks and set_all on instance
dev-davexoyinbo 37a0883
feat: set all
dev-davexoyinbo 07f780c
feat: add instance wide mutex to prevent deadlock
dev-davexoyinbo b29ab5a
feat: allow lag for the instance_wide lock
dev-davexoyinbo 0a7080a
test: update tests
dev-davexoyinbo 000ea63
feat: update counter trait
dev-davexoyinbo ac38936
feat: comparator
dev-davexoyinbo 377d877
feat: update traits
dev-davexoyinbo 8688cfb
test: lax counter for confitional inc and set
dev-davexoyinbo fa4f58e
test: strict counter test
dev-davexoyinbo a606a2f
feat: strict counter update for conditionals
dev-davexoyinbo 2d9cbcd
feat: lax_counter
dev-davexoyinbo 82209f5
test: lax instance aware for conditionals
dev-davexoyinbo 1ea2369
test: strict instance aware
dev-davexoyinbo 079262c
feat: comparator lax instance aware
dev-davexoyinbo 20230d0
feat: comparison strict instance aware
dev-davexoyinbo 721b8e3
test: inc_if and inc_all_if
dev-davexoyinbo c19e63a
feat: add inc all if to traits
dev-davexoyinbo 2d7ac1b
feat: inc and inc all if
dev-davexoyinbo e15cedb
feat: inc_all_if
dev-davexoyinbo 0546165
feat: rename RedisKit and update docs
dev-davexoyinbo f2a2db8
feat: update bench
dev-davexoyinbo c94a595
bump version v0.3.0
dev-davexoyinbo File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,102 @@ | ||
| # CLAUDE.md | ||
|
|
||
| This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. | ||
|
|
||
| ## Commands | ||
|
|
||
| ```bash | ||
| make test # Start Redis, run full test suite, tear down | ||
| make bench # Start Redis, run criterion benchmarks, tear down | ||
| make redis-up # Start Redis only (docker-compose, port REDIS_PORT=16379) | ||
| make redis-down # Stop Redis and remove volumes | ||
| ``` | ||
|
|
||
| To run tests manually (Redis must be running): | ||
| ```bash | ||
| REDIS_URL="redis://127.0.0.1:16379/" cargo test --all-features | ||
| REDIS_URL="redis://127.0.0.1:16379/" cargo test --all-features <test_name> # single test | ||
| cargo test --doc --all-features # doctests only | ||
| ``` | ||
|
|
||
| **Always use `make test`, not bare `cargo test`** — tests require `REDIS_URL` to be set and a live Redis instance. | ||
|
|
||
| ## Architecture | ||
|
|
||
| **distkit** is an async Rust library (Tokio + Redis) providing distributed counting primitives with two consistency modes and two counter families. | ||
|
|
||
| ### Counter families | ||
|
|
||
| | Family | Trait | Strict impl | Lax impl | | ||
| |--------|-------|-------------|----------| | ||
| | Simple | `CounterTrait` | `StrictCounter` | `LaxCounter` | | ||
| | Instance-aware | `InstanceAwareCounterTrait` | `StrictInstanceAwareCounter` | `LaxInstanceAwareCounter` | | ||
|
|
||
| **Strict** counters: every operation is an atomic Lua script round-trip — fully consistent. | ||
|
|
||
| **Lax** counters: `inc`/`dec`/`get`/`set_on_instance` are served from an in-memory `DashMap`; a background Tokio task flushes accumulated deltas to Redis every `flush_interval` (default 20 ms). Epoch-bumping operations (`set`, `del`, `clear`) flush first, then delegate to the strict backend. The background task holds a `Weak` reference and stops when the counter is dropped. | ||
|
|
||
| ### Instance-aware counters | ||
|
|
||
| Each counter instance gets a UUID. Operations return `(cumulative, instance_count)`. Redis stores: | ||
| - `cumulative_key` hash: key → global total | ||
| - `instance_count_key` hash: per-instance contributions | ||
| - `instances_key` sorted set: instance_id → last-heartbeat timestamp (ms) | ||
| - `epoch_key` hash: per-key epoch counter (bumped by `set`/`del` to invalidate stale slices) | ||
|
|
||
| Dead instances (no heartbeat for `dead_instance_threshold_ms`, default 30 s) are cleaned up by the next live instance that touches an affected key. | ||
|
|
||
| ### Lua scripts | ||
|
|
||
| All Redis logic is embedded as inline Lua strings inside each `*_counter.rs` file — no external `.lua` files. `HELPERS_LUA` (in `strict_instance_aware_counter.rs`) defines shared helpers (`now_ms`, `delete_dead_instances`, `check_and_zadd`) that are prepended to every icounter script via string concatenation. | ||
|
|
||
| Scripts echo keys back in their return values so callers can build `HashMap<String, T>` results instead of relying on positional ordering. **Never use `.zip()` to align pipeline results with input keys** — use the HashMap keyed on the returned key string. | ||
|
|
||
| ### `execute_pipeline_with_script_retry` | ||
|
|
||
| `src/common/mod.rs` exports this generic helper used by every batch pipeline operation: | ||
|
|
||
| ```rust | ||
| execute_pipeline_with_script_retry(conn, script, items, |item| { | ||
| let mut inv = script.key(...); | ||
| inv.key(...).arg(...); | ||
| inv // return owned ScriptInvocation | ||
| }) | ||
| ``` | ||
|
|
||
| On `NOSCRIPT` error it prepends `load_script` and retries the entire pipeline. Callers pass a closure returning one `ScriptInvocation<'s>` per item; the function owns all pipeline mechanics. | ||
|
|
||
| ### `RedisKey` | ||
|
|
||
| Newtype wrapping `String`, validated on construction (`TryFrom<String>`): non-empty, ≤255 chars, no colons. Used as the public API key type throughout. `RedisKeyGenerator` prepends the counter-type prefix when building actual Redis keys. | ||
|
|
||
| ### `ActivityTracker` | ||
|
|
||
| Drives the lax flush task's sleep/wake cycle. `signal()` sets `is_active = true` atomically and sends on a `watch` channel. The flush task parks at `is_active_watch.changed()` when idle; `run_is_active_task` sets `is_active = false` after `epoch_interval / 2` (7.5 s) of inactivity. The epoch advances every `EPOCH_CHANGE_INTERVAL` (15 s); `signal()` is a no-op within the same epoch to avoid redundant sends. | ||
|
|
||
| ### Feature flags | ||
|
|
||
| - `counter` (default): `StrictCounter`, `LaxCounter` | ||
| - `instance-aware-counter` (default): `StrictInstanceAwareCounter`, `LaxInstanceAwareCounter` | ||
| - `trypema`: re-exports the `trypema` rate-limiting crate | ||
|
|
||
| ### Module layout | ||
|
|
||
| ``` | ||
| src/ | ||
| lib.rs # feature-gated re-exports | ||
| error.rs # DistkitError | ||
| common/ | ||
| mod.rs # RedisKey, RedisKeyGenerator, execute_pipeline_with_script_retry, | ||
| # ActivityTracker, EPOCH_CHANGE_INTERVAL | ||
| counter/ | ||
| counter_trait.rs # CounterTrait (async_trait) | ||
| strict_counter.rs # StrictCounter + embedded Lua | ||
| lax_counter.rs # LaxCounter + embedded Lua | ||
| tests/ # unit tests per impl | ||
| icounter/ | ||
| mod.rs # InstanceAwareCounterTrait (async_trait) | ||
| strict_instance_aware_counter.rs # StrictInstanceAwareCounter + all Lua scripts | ||
| lax_instance_aware_counter.rs # LaxInstanceAwareCounter (wraps strict) | ||
| tests/ | ||
| __doctest_helpers.rs # Counter factory helpers for inline doc examples | ||
| ``` | ||
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
1. cargo test --doc missing redis_url
📘 Rule violation☼ ReliabilityAgent Prompt
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools