feat(backend): Redis lock + Workers lock/TTL capability parity (LAB-426) - #37
Conversation
…y impls
Backend capability parity per the LAB-273 audit:
- RedisBackend gains LockableBackend: SET NX PX acquire with a UUID
capability token, atomic Lua compare-and-delete release. Callers pass
the bare cache key; the backend derives <key>:lock on the wire,
byte-identical to cachekit-py's Redis lock namespace so py and rs
workloads contend on the same lock. Needs fred's i-scripts feature
for EVAL.
- WorkersCachekitIO gains LockableBackend + TtlInspectable against the
same SaaS endpoints the native CachekitIO impls call. The lock token
travels in X-CacheKit-Lock-Id, never the query string (CWE-532).
Contested acquire is 200 {"lock_id": null} — branched on the body,
never on a 409 status (protocol#22 / LAB-240).
- SaaS lock/TTL JSON bodies live in backend/saas_wire.rs with literal
wire-JSON round-trip tests compiled under cfg(test) unconditionally,
so the snake_case contract is enforced in native CI (guards against
the LAB-411 camelCase serde regression).
- Live Redis lock semantics covered by an env-gated integration test
(CACHEKIT_TEST_REDIS_URL): acquire, contested None, foreign-token
release refusal, double release, TTL self-expiry, wire key shape.
Co-authored-by: multica-agent <github@multica.ai>
|
Warning Review limit reachedYou’ve reached a temporary PR review limit under our Fair Usage Limits Policy. Next review available in: 20 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (3)
WalkthroughAdds distributed locking to the Redis backend, lock and TTL operations to the Workers backend, shared SaaS JSON wire contracts, live Redis integration coverage, CI execution, and corresponding documentation. ChangesDistributed backend capabilities
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant Client
participant WorkersCachekitIO
participant SaaSEndpoints
Client->>WorkersCachekitIO: Request lock or TTL operation
WorkersCachekitIO->>SaaSEndpoints: Send JSON HTTP request
SaaSEndpoints-->>WorkersCachekitIO: Return JSON response or status
WorkersCachekitIO-->>Client: Return lock token, TTL, or operation result
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
|
@coderabbitai full review |
✅ Action performedFull review finished. Your included review limit is currently reached under our Fair Usage Limits Policy. Your recent PR review activity is in the 95th percentile or higher among CodeRabbit users, so adaptive limits apply. This review may still proceed through usage-based billing if eligible. Your next included review will be available in 1 minute. |
Expert-panel review (crypto/protocol gate) — verdict: SHIP ✅Per the project's mandatory crypto/protocol gate (this PR derives an on-wire Crypto/protocol gate: SATISFIED — no surviving in-diff findings. Security returned clean after tracing every new path:
No CRIT/MAJ in-diff. Disposition of the non-blocking findings, in writing:
Panel verdict stands: clean, lean, correctly scoped. Ready for human signoff once CodeRabbit completes (a full re-review was forced — CR had only posted a rate-limit banner at open, never a substantive review). |
…ner (LAB-426) Co-authored-by: multica-agent <github@multica.ai>
…rom_response Co-authored-by: multica-agent <github@multica.ai>
There was a problem hiding this comment.
Actionable comments posted: 4
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/workflows/ci.yml:
- Line 66: Update the self-hosted-runner.labels configuration in
.github/actionlint.yaml to register the new cachekit runner label alongside the
existing cachekit-lean label, so the runs-on value in the CI workflow is
recognized.
- Line 79: Update the actions/checkout step in the CI workflow to set
persist-credentials to false, ensuring the checkout token is not retained on the
self-hosted runner; leave the existing checkout action version unchanged.
- Around line 68-77: Update the Redis service image in the workflow to use an
immutable SHA256 digest instead of the mutable redis:7 tag, while preserving the
existing Redis service configuration and health-check options.
In `@README.md`:
- Line 216: Update the README statement about the wasm32 Workers backend to
remove the claim of identical locking and TTL-inspection parity with native
SaaS; describe Workers support without asserting full parity until the shared
SaaS wire format is corrected.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: 88319dcc-b860-46d8-9849-71ff3212a456
📒 Files selected for processing (8)
.github/workflows/ci.ymlREADME.mdcrates/cachekit/Cargo.tomlcrates/cachekit/src/backend/mod.rscrates/cachekit/src/backend/redis.rscrates/cachekit/src/backend/saas_wire.rscrates/cachekit/src/backend/workers.rscrates/cachekit/tests/redis_tests.rs
… checkout creds, README wording - Register cachekit-lean + cachekit self-hosted labels in .github/actionlint.yaml so actionlint (CodeRabbit runs it) recognises runs-on values. - Pin the redis:7 service image to its OCI index digest (resolved from Docker Hub 2026-07-23) — matches the SHA-pinned actions posture. - persist-credentials: false on the redis-lock job checkout; it never pushes and the runner is self-hosted (zizmor artipacked). - README: describe Workers lock/TTL support without claiming parity with the native SaaS backend while its lock wire format is still camelCase-broken pending #34 (LAB-411). CodeRabbit-Resolved: .github/workflows/ci.yml:66:Unknown cachekit runner label CodeRabbit-Resolved: .github/workflows/ci.yml:77:Pin the redis:7 service image CodeRabbit-Resolved: .github/workflows/ci.yml:79:Set persist-credentials false CodeRabbit-Resolved: README.md:216:Avoid claiming full parity Co-authored-by: multica-agent <github@multica.ai>
|
@coderabbitai review |
✅ Action performedReview finished.
|
Closes LAB-426. Backend capability parity per the LAB-273 audit: Redis gains distributed locking; the Workers backend gains locking + TTL inspection against the SaaS it already speaks.
What
impl LockableBackend for RedisBackend(redis.rs) —SET NX PXacquire returning a generated UUID capability token; release via atomic Lua compare-and-delete (only the token holder can release, and expiry races can't delete someone else's lock). Honours the bare-cache-key contract: callers pass the bare key, the backend derives<key>:lockon the wire — byte-identical to cachekit-py's Redis lock namespace, so py and rs workloads contend on the same lock. Requires fred'si-scriptsfeature forEVAL(added to the feature activation, default fred features unchanged).impl LockableBackend for WorkersCachekitIO(workers.rs) — same SaaS lock endpoint as the nativeCachekitIOimpl. The lock token travels in theX-CacheKit-Lock-Idheader, never?lock_id=(CWE-532). Contested acquire is200 {"lock_id": null}— branched on the body, never on a 409 status (protocol#22 / LAB-240 canonical shape).impl TtlInspectable for WorkersCachekitIO— sameGET/PATCH /v1/cache/{key}/ttlendpoints as the native impl, including therefresh_ttlzero-seconds guard and 404→None/falsemapping.workers.rsfetch()learnsPOST/PATCH, plus anerror_from_responsehelper mirroring the native backend's.workersfeature now activatesdep:serde_json(previously only pulled in viacachekitio).Wire-contract enforcement (LAB-411 guard)
The SaaS lock/TTL JSON bodies live in a new
backend/saas_wire.rs, compiled undercfg(test)unconditionally so its tests run in the default native CI suite even though only theworkersbackend consumes the structs at runtime. Tests pin literal wire JSON ({"timeout_ms":5000},{"lock_id":null},{"ttl":3542}) rather than round-tripping structs with themselves, and include an explicit camelCase tripwire ({"lockId":"x"}must fail to parse). This does not touchcachekitio_lock.rs— the standalone LAB-411 fix stays in #34.Tests
<key>:lockderivation,dyn LockableBackendcompile proofs) — run in default CI.redis_lock_live_semanticsintegration test, env-gated onCACHEKIT_TEST_REDIS_URL(CI has no Redis service; skips with a notice). Proven locally against a realredis-server: acquire → token stored at<key>:lock; contested acquire →None; foreign-token release refused; holder release →true; double release →false; reacquire after release;timeout_msTTL self-expiry.Verification matrix (all local, all green)
cargo test --features "cachekitio,redis,encryption,l1,macros"(CI-equivalent) — plus the same with a live Rediscargo clippy --all-targets --features "cachekitio,redis,encryption,l1,macros" -- -D warningscargo check --target wasm32-unknown-unknown --features workers,encryption --no-default-features(CI wasm job)cargo checkwith--no-default-features, default,redis,unsync,unsync,cachekitio,rediscargo fmt --all -- --checkDocs
README backend sections updated (Redis + Workers capability claims, project layout). Companion PR on
protocolflips the rs Redis-lock / Workers-lock / Workers-TTL matrix cells — that PR should merge only after (or with) this one.Summary by CodeRabbit
New Features
Bug Fixes
Documentation
Tests