Skip to content

feat(cache): replace zone io lock with striped io locks#72

Merged
vansour merged 3 commits intomainfrom
feat/cache-fine-grained-io-locking
Apr 29, 2026
Merged

feat(cache): replace zone io lock with striped io locks#72
vansour merged 3 commits intomainfrom
feat/cache-fine-grained-io-locking

Conversation

@vansour
Copy link
Copy Markdown
Owner

@vansour vansour commented Apr 29, 2026

Summary

  • replace the cache zone global io_lock with striped per-hash RwLock I/O coordination
  • switch cache read/write/revalidate/purge/cleanup paths to the new hash-scoped locking model
  • harden cache entry removal with compare-and-remove plus hash reference checks, and document the architecture gap as completed

Testing

  • cargo test -p rginx-http cache --quiet
  • cargo test -p rginx-http --lib --quiet
  • python3 ./scripts/run-modularization-gate.py

Copilot AI review requested due to automatic review settings April 29, 2026 05:51
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 29, 2026

Warning

Rate limit exceeded

@vansour has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 21 minutes and 2 seconds before requesting another review.

To keep reviews running without waiting, you can enable usage-based add-on for your organization. This allows additional reviews beyond the hourly cap. Account admins can enable it under billing.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI (base), Organization UI (inherited)

Review profile: ASSERTIVE

Plan: Pro

Run ID: 8d36db03-7ede-421a-be2a-9a33d29c97fd

📥 Commits

Reviewing files that changed from the base of the PR and between 591d314 and 4004233.

📒 Files selected for processing (18)
  • crates/rginx-http/src/cache/index.rs
  • crates/rginx-http/src/cache/io.rs
  • crates/rginx-http/src/cache/load.rs
  • crates/rginx-http/src/cache/mod.rs
  • crates/rginx-http/src/cache/runtime.rs
  • crates/rginx-http/src/cache/runtime/support.rs
  • crates/rginx-http/src/cache/shared/index_file/codec.rs
  • crates/rginx-http/src/cache/shared/index_file/sqlite.rs
  • crates/rginx-http/src/cache/store.rs
  • crates/rginx-http/src/cache/store/maintenance/index_state.rs
  • crates/rginx-http/src/cache/store/maintenance/mod.rs
  • crates/rginx-http/src/cache/store/revalidate.rs
  • crates/rginx-http/src/cache/tests/lookup/background.rs
  • crates/rginx-http/src/cache/tests/lookup/recovery.rs
  • crates/rginx-http/src/cache/tests/notifications.rs
  • crates/rginx-http/src/cache/tests/storage.rs
  • crates/rginx-http/src/cache/tests/storage_p1.rs
  • crates/rginx-http/src/cache/tests/storage_regressions.rs
📝 Walkthrough

演讲稿

本次变更将缓存系统的区域级全局 io_lock 互斥锁替换为基于哈希的条纹化 CacheIoLockPool,包含 64 个独立的 RwLock 条纹。新增哈希作用域的 io_read()io_write() 方法支持比较后移除的语义,并在多个缓存模块中更新锁定逻辑以使用条纹池而非全局锁。

变更项

缓存I/O锁设施 摘要
核心锁池实现
crates/rginx-http/src/cache/io.rs
引入 CacheIoLockPool,管理 64 个条纹化的 RwLock<()>,支持基于哈希的读/写卫士类型,以及批量哈希写锁获取(去重并按确定顺序)。
CacheZoneRuntime更新
crates/rginx-http/src/cache/mod.rs
io_lock: AsyncMutex<()> 替换为 io_locks: CacheIoLockPool,为 CacheIndexEntryCachedVaryHeaderValue 增加 PartialEq/Eq/Debug 派生。
缓存查询与锁定
crates/rginx-http/src/cache/lookup.rs, crates/rginx-http/src/cache/manager.rs
从全局 io_lock 切换至哈希作用域的 zone.io_read(&entry.hash);整合多个移除操作到单一条件移除调用。
缓存运行时支持
crates/rginx-http/src/cache/runtime.rs, crates/rginx-http/src/cache/runtime/support.rs
采用 zone.io_read(&entry.hash) 替代全局锁;新增 remove_cache_entry_if_matches() 支持比较后移除;更新 remove_cache_files_if_unreferenced() 返回 bool 并实施哈希作用域锁定。
存储与重验证
crates/rginx-http/src/cache/store.rs, crates/rginx-http/src/cache/store/maintenance/index_state.rs, crates/rginx-http/src/cache/store/maintenance/mod.rs, crates/rginx-http/src/cache/store/revalidate.rs
使用哈希作用域的 io_write() 替代全局锁;重构 remove_zone_index_entry()remove_zone_index_entry_if_matches(),返回 RemovedIndexEntry 结构体;文件删除逻辑改为针对已移除哈希的条件删除。
测试覆盖
crates/rginx-http/src/cache/tests/mod.rs, crates/rginx-http/src/cache/tests/storage_p1.rs, crates/rginx-http/src/cache/tests/storage_regressions.rs
更新测试辅助函数使用 CacheIoLockPool;新增两项回归测试验证不同哈希的条纹不相互阻塞,以及并发重写期间的移除安全性。
文档更新
docs/CACHE_ARCHITECTURE_GAPS.md
将解决的架构差距从长期项移至已收敛项,记录全局锁替换为条纹化 RwLock 及比较后移除语义的改进。

预估代码审查工作量

🎯 3 (中等复杂度) | ⏱️ ~25 分钟

可能相关的PR

诗篇

🐰 条纹替代锁,哈希各得所,

并发不再堵,缓存轻飘飘。

比较后才删,安全有保障,

小兔献一歌!🐇✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 15.63% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat(cache): replace zone io lock with striped io locks' accurately and concisely captures the main change: replacing a single global I/O lock with a striped per-hash locking mechanism.
Description check ✅ Passed The description clearly relates to the changeset, detailing the replacement of the zone-level io_lock with striped per-hash RwLock coordination and updates to cache subsystem paths, with appropriate testing commands.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/cache-fine-grained-io-locking

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
Review rate limit: 0/1 reviews remaining, refill in 21 minutes and 2 seconds.

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@amazon-q-developer amazon-q-developer Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Summary

This PR successfully replaces the zone-level global io_lock with a striped lock pool, significantly improving cache I/O concurrency. The implementation is well-designed and correctly addresses the architecture gap documented in CACHE_ARCHITECTURE_GAPS.md.

Key Improvements

  • Reduced contention: Different hash files no longer share a single zone-level I/O bottleneck
  • Fine-grained locking: Conflicts are now scoped to hash/stripe level rather than entire zone
  • Race condition fix: Compare-and-remove pattern with hash reference checks prevents deletion of concurrently rewritten files

Implementation Quality

  • Clean separation of concerns with dedicated io.rs module
  • Proper use of BTreeSet to acquire locks in deterministic order (prevents deadlocks)
  • Comprehensive test coverage including striping validation and race condition scenarios
  • Documentation updated to mark this gap as completed

The changes are ready to merge.


You can now have the agent implement changes and create commits directly on your pull request's source branch. Simply comment with /q followed by your request in natural language to ask the agent to make changes.

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request replaces the global cache I/O lock with a fine-grained, striped RwLock pool to improve concurrency and throughput. It also introduces a compare-and-remove mechanism for cache entries to resolve race conditions between entry removal and concurrent writes. The review feedback highlights critical performance concerns regarding O(N) index scans during file cleanup and potential logic errors in entry comparisons caused by volatile timestamp fields in the CacheIndexEntry struct.

Comment thread crates/rginx-http/src/cache/runtime/support.rs Outdated
Comment thread crates/rginx-http/src/cache/store/maintenance/index_state.rs Outdated
Comment thread crates/rginx-http/src/cache/store/maintenance/index_state.rs Outdated
Comment thread crates/rginx-http/src/cache/store/maintenance/mod.rs Outdated
coderabbitai[bot]
coderabbitai Bot previously requested changes Apr 29, 2026
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
crates/rginx-http/src/cache/store/revalidate.rs (1)

86-103: ⚠️ Potential issue | 🔴 Critical

关键并发竞态:释放 io_write 后再删文件会产生 TOCTOU。

Line 86-96 的写锁在执行索引删除与 remove_file 之前就已释放。此窗口内并发写入可复用同一 hash 文件,随后被当前分支误删。

建议修复(将索引删除与文件删除纳入同一 `io_write` 作用域)
-        let refreshed = {
-            let _io_guard = context.zone.io_write(&cached_entry.hash).await;
-            build_cached_response_for_request(
-                &paths.body,
-                &metadata,
-                &context.request,
-                &context.policy,
-                context.read_cached_body,
-            )
-            .await
-            .map_err(|error| CacheStoreError { source: Box::new(error) })?
-        };
-        if let Some(removed) =
-            remove_zone_index_entry_if_matches(&context.zone, &context.key, &cached_entry).await
-            && removed.delete_files
-        {
-            let _ = fs::remove_file(&paths.metadata).await;
-            let _ = fs::remove_file(&paths.body).await;
-        }
+        let refreshed = {
+            let _io_guard = context.zone.io_write(&cached_entry.hash).await;
+            let refreshed = build_cached_response_for_request(
+                &paths.body,
+                &metadata,
+                &context.request,
+                &context.policy,
+                context.read_cached_body,
+            )
+            .await
+            .map_err(|error| CacheStoreError { source: Box::new(error) })?;
+
+            if let Some(removed) = remove_zone_index_entry_if_matches(
+                &context.zone,
+                &context.key,
+                &cached_entry,
+            )
+            .await
+                && removed.delete_files
+            {
+                let _ = fs::remove_file(&paths.metadata).await;
+                let _ = fs::remove_file(&paths.body).await;
+            }
+            refreshed
+        };
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@crates/rginx-http/src/cache/store/revalidate.rs` around lines 86 - 103, The
io_write guard is being dropped before you call
remove_zone_index_entry_if_matches and remove_file, creating a TOCTOU where
another writer can reuse the same hash and cause accidental deletion; to fix,
acquire and hold the write lock returned by
context.zone.io_write(&cached_entry.hash).await across the index removal and
file deletions (i.e., keep the _io_guard live until after you call
remove_zone_index_entry_if_matches(&context.zone, &context.key,
&cached_entry).await and, if removed.delete_files, perform
fs::remove_file(&paths.metadata).await and fs::remove_file(&paths.body).await
while still holding the guard), so the index mutation and physical file removals
occur inside the same io_write critical section that protects cached_entry.hash.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@crates/rginx-http/src/cache/runtime/support.rs`:
- Around line 81-85: The remove_cache_files function currently swallows errors
from fs::remove_file for paths.metadata and paths.body; update
remove_cache_files (and keep using cache_paths_for_zone and the zone:
&rginx_core::CacheZone, hash: &str parameters) to check the Result of each
fs::remove_file and log a warning or debug entry on failure that includes the
hash, the path (paths.metadata / paths.body), and the error (e.g., via
tracing::warn! or log::warn!), so failures due to permissions or filesystem
issues are observable.

In `@crates/rginx-http/src/cache/store/maintenance/index_state.rs`:
- Around line 64-67: The current equality check compares the whole entry struct
(used in remove_cache_entry_if_matches / index.entries.get) which fails when
volatile fields like last_access_unix_ms change; update the comparison to only
compare stable identity fields (e.g., entry.hash and entry.base_key) or use a
dedicated version/id field if available, and leave timestamp fields out of the
equality test so concurrent updates to last_access_unix_ms won't prevent a valid
match and removal.

In `@crates/rginx-http/src/cache/tests/storage_regressions.rs`:
- Around line 236-240: io_stripe is tightly coupled to an implementation detail
(hardcoded "% 64" and DefaultHasher) which may diverge from the real sharding in
CacheIoLockPool; change the test to reuse the production shard logic or
configuration instead of duplicating it: call the public shard function or read
the shard count/stripe function exported by the cache/io lock pool (e.g., use
CacheIoLockPool's stripe function or its IO lock shard constant) so the test
uses the same hashing+modulo behavior as the production code and remove the
hardcoded "% 64" and standalone DefaultHasher usage.

---

Outside diff comments:
In `@crates/rginx-http/src/cache/store/revalidate.rs`:
- Around line 86-103: The io_write guard is being dropped before you call
remove_zone_index_entry_if_matches and remove_file, creating a TOCTOU where
another writer can reuse the same hash and cause accidental deletion; to fix,
acquire and hold the write lock returned by
context.zone.io_write(&cached_entry.hash).await across the index removal and
file deletions (i.e., keep the _io_guard live until after you call
remove_zone_index_entry_if_matches(&context.zone, &context.key,
&cached_entry).await and, if removed.delete_files, perform
fs::remove_file(&paths.metadata).await and fs::remove_file(&paths.body).await
while still holding the guard), so the index mutation and physical file removals
occur inside the same io_write critical section that protects cached_entry.hash.
🪄 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: Repository UI (base), Organization UI (inherited)

Review profile: ASSERTIVE

Plan: Pro

Run ID: 5de61607-926c-4c71-89aa-37f3dc739dda

📥 Commits

Reviewing files that changed from the base of the PR and between 402d28d and 591d314.

📒 Files selected for processing (14)
  • crates/rginx-http/src/cache/io.rs
  • crates/rginx-http/src/cache/lookup.rs
  • crates/rginx-http/src/cache/manager.rs
  • crates/rginx-http/src/cache/mod.rs
  • crates/rginx-http/src/cache/runtime.rs
  • crates/rginx-http/src/cache/runtime/support.rs
  • crates/rginx-http/src/cache/store.rs
  • crates/rginx-http/src/cache/store/maintenance/index_state.rs
  • crates/rginx-http/src/cache/store/maintenance/mod.rs
  • crates/rginx-http/src/cache/store/revalidate.rs
  • crates/rginx-http/src/cache/tests/mod.rs
  • crates/rginx-http/src/cache/tests/storage_p1.rs
  • crates/rginx-http/src/cache/tests/storage_regressions.rs
  • docs/CACHE_ARCHITECTURE_GAPS.md
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Agent
  • GitHub Check: Test Fast
🧰 Additional context used
🪛 LanguageTool
docs/CACHE_ARCHITECTURE_GAPS.md

[uncategorized] ~62-~62: 您的意思是“"不"齐”?
Context: ...台波动 - 让缓存维护任务在高负载下仍保持可预测的延迟特征 ### 3. 补齐 range / stale / revalidate / policy 的长...

(BU)

🔇 Additional comments (13)
docs/CACHE_ARCHITECTURE_GAPS.md (1)

19-33: 文档收敛项与长期差距拆分清晰。

已完成项说明、日期标注与后续章节重编号一致,便于后续追踪与维护。

Also applies to: 49-50, 62-63, 76-77

crates/rginx-http/src/cache/tests/storage_p1.rs (1)

248-248: 测试运行时锁模型更新正确。

Line 248 将测试构造切换到 CacheIoLockPool,与生产路径并发模型保持一致。

crates/rginx-http/src/cache/tests/mod.rs (1)

49-49: 测试辅助构造与新并发语义对齐。

Line 49 的替换是必要同步更新,避免测试继续依赖 zone 级旧锁。

crates/rginx-http/src/cache/store.rs (1)

34-37: 写入路径并发控制与维护 API 迁移都合理。

Line 119 的 hash 级写锁与 Line 36 的 match-based 删除接口重导出是同一语义收敛,设计一致。

Also applies to: 119-119

crates/rginx-http/src/cache/manager.rs (1)

33-33: Manager 命中读路径和故障清理路径收敛良好。

Line 93 的 hash 级读锁与 Line 119 的条件删除组合,能更好避免跨 key 的不必要串行化。

Also applies to: 93-93, 119-119

crates/rginx-http/src/cache/io.rs (1)

11-65: 条带化 I/O 锁池实现设计合理。

按 stripe 去重并按有序集合加锁的实现,保证了多哈希写锁获取顺序的确定性。

crates/rginx-http/src/cache/lookup.rs (1)

109-109: lookup 读路径与异常清理路径统一且正确。

Line 109 与 Line 165 的读锁引入,以及失败后统一条件删除,能显著减少误删窗口。

Also applies to: 122-123, 134-135, 146-147, 164-218

crates/rginx-http/src/cache/store/revalidate.rs (1)

107-141: 元数据写回后再更新索引与返回响应的顺序正确。

Line 107-141 在同一写锁作用域内完成写回、统计和索引更新,时序是稳健的。

crates/rginx-http/src/cache/runtime.rs (1)

108-109: 细粒度 I/O 锁与条件删除路径实现正确。

Line 108 切到 hash 级读锁、Line 135 使用 compare-and-remove,能避免 zone 级串行化和误删已被替换的条目,和本次并发模型目标一致。

Also applies to: 135-136

crates/rginx-http/src/cache/tests/storage_regressions.rs (1)

145-234: 并发回归场景覆盖到位。

该用例验证了“同 hash 写锁持有期间,旧条目移除不会误删新重写内容”的关键竞态窗口,能有效守护本 PR 的核心并发语义。

crates/rginx-http/src/cache/store/maintenance/mod.rs (1)

70-76: 基于 hash 去重 + unreferenced 删除策略实现合理。

这里将文件删除从“直接删”改为“按 hash 去重后按引用关系删”,并统一走 remove_cache_files_if_unreferenced,可以显著降低并发下误删同 hash 共享文件的风险。

Also applies to: 124-130, 145-146, 219-220

crates/rginx-http/src/cache/runtime/support.rs (1)

7-35: 条件移除与“仅在无引用时删文件”的执行顺序正确。

先拿 hash 写锁,再做 compare-and-remove,再按 delete_files 决策删除,能保证该路径在并发下的安全性和可预期性。

crates/rginx-http/src/cache/mod.rs (1)

19-19: 类型与运行时结构调整方向正确。

io_locks: CacheIoLockPoolCacheIndexEntry/CachedVaryHeaderValuePartialEq/Eq 补齐了本 PR 新锁模型和条件删除 API 的基础能力,设计上是一致且必要的。

Also applies to: 36-36, 46-47, 155-155, 174-175, 211-212

Comment thread crates/rginx-http/src/cache/runtime/support.rs Outdated
Comment thread crates/rginx-http/src/cache/store/maintenance/index_state.rs
Comment thread crates/rginx-http/src/cache/tests/storage_regressions.rs Outdated
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR replaces a cache-zone global I/O mutex with hash-striped RwLock coordination to improve concurrency, and hardens cache entry deletion to avoid removing newly rewritten files.

Changes:

  • Introduces CacheIoLockPool (64 stripes) and migrates cache read/write/revalidate/maintenance paths to io_read/io_write.
  • Updates purge/cleanup/eviction deletion to only remove cache files when the hash is unreferenced.
  • Adds regression tests for cross-stripe non-blocking behavior and stale-removal vs. in-flight rewrite races.

Reviewed changes

Copilot reviewed 14 out of 14 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
docs/CACHE_ARCHITECTURE_GAPS.md Marks the zone-global io_lock gap as completed and documents the new striped locking model.
crates/rginx-http/src/cache/io.rs Adds striped per-hash RwLock pool and CacheZoneRuntime::io_read/io_write helpers.
crates/rginx-http/src/cache/mod.rs Wires in the new I/O lock pool and adds PartialEq/Eq to index entry structs to support compare-and-remove.
crates/rginx-http/src/cache/store.rs Uses io_write(hash) for store path and keeps coordination aligned with the new lock model.
crates/rginx-http/src/cache/store/revalidate.rs Switches revalidation to hash-scoped I/O locks and compare-and-remove index deletion.
crates/rginx-http/src/cache/store/maintenance/mod.rs Updates cleanup/purge/eviction to delete files via “unreferenced hash” checks instead of a global I/O lock.
crates/rginx-http/src/cache/store/maintenance/index_state.rs Introduces remove_zone_index_entry_if_matches returning whether files should be deleted.
crates/rginx-http/src/cache/runtime/support.rs Adds remove_cache_entry_if_matches and remove_cache_files_if_unreferenced helpers.
crates/rginx-http/src/cache/runtime.rs Routes stale/invalid entry cleanup through the new compare-and-remove deletion helper.
crates/rginx-http/src/cache/manager.rs Updates hit path to use io_read and cleanup via compare-and-remove removal helper.
crates/rginx-http/src/cache/lookup.rs Updates metadata/body reads to io_read and cleanup via compare-and-remove removal helper.
crates/rginx-http/src/cache/tests/mod.rs Updates test zone construction to use CacheIoLockPool.
crates/rginx-http/src/cache/tests/storage_p1.rs Updates test runtime construction to use CacheIoLockPool.
crates/rginx-http/src/cache/tests/storage_regressions.rs Adds tests for stripe isolation and stale removal vs rewrite safety.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread crates/rginx-http/src/cache/store/revalidate.rs Outdated
Comment thread crates/rginx-http/src/cache/store/maintenance/mod.rs Outdated
Comment thread crates/rginx-http/src/cache/store/maintenance/mod.rs
Comment thread crates/rginx-http/src/cache/store/maintenance/index_state.rs
@vansour
Copy link
Copy Markdown
Owner Author

vansour commented Apr 29, 2026

已处理本轮 review 提到的并发和实现问题,并已推送到 2f69e76

本次修复包括:

  • 修复 store/revalidate.rs 里 no-store 分支释放 io_write 后再删文件的 TOCTOU,文件删除现在保留在同一个 hash 写锁作用域内
  • 解决 update_index_after_store() 在调用方持有 io_write 时再次按 hash 删除文件的潜在死锁,改为只返回待清理 hash,由调用方在释放当前写锁后再清理
  • CacheIndex 增加 hash 引用计数,去掉删除路径里的 O(N) 全表扫描
  • compare-and-remove 改为使用稳定字段比较,不再受 last_access_unix_ms 漂移影响
  • 测试改为复用生产分片函数,并新增两条回归测试覆盖 last_access 漂移场景
  • 文件删除失败现在会记录日志

已重新验证:

  • cargo test -p rginx-http cache --quiet
  • cargo test -p rginx-http --lib --quiet
  • python3 ./scripts/run-modularization-gate.py

@vansour vansour dismissed coderabbitai[bot]’s stale review April 29, 2026 06:52

Addressed in commits 2f69e76 and 4004233; dismissing stale bot review before merge.

@vansour vansour merged commit 20de806 into main Apr 29, 2026
7 checks passed
@vansour vansour deleted the feat/cache-fine-grained-io-locking branch April 29, 2026 06:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants