Add optional disk cache and bump to v0.1.2#11
Conversation
Co-authored-by: GrassBlock1 <46253950+GrassBlock1@users.noreply.github.com>
Co-authored-by: GrassBlock1 <46253950+GrassBlock1@users.noreply.github.com>
Co-authored-by: GrassBlock1 <46253950+GrassBlock1@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Adds an optional persistent disk-backed cache layer for media responses (memory → disk → upstream) and bumps the crate version to 0.1.2, including documentation/config updates and expanded metrics.
Changes:
- Introduced
src/disk_cache.rsimplementing hashed on-disk storage with TTL checks and size-limit eviction, plus unit tests. - Extended
ResponseCacheto optionally consult/promote from disk cache and expose disk-cache stats via/metrics. - Added config knobs (
disk_cache_enabled,disk_cache_path,disk_cache_max_size) and bumped version + changelog/docs.
Reviewed changes
Copilot reviewed 9 out of 11 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
src/proxy.rs |
Initializes optional disk cache and expands /metrics with disk-cache stats. |
src/main.rs |
Registers the new disk_cache module. |
src/disk_cache.rs |
New disk cache implementation (hashing, TTL, eviction) + tests. |
src/config.rs |
Adds disk cache configuration fields + defaults. |
src/cache.rs |
Adds disk-cache fallback/promote logic and disk stats to cache stats. |
config.example.toml |
Documents new disk cache configuration options. |
README.md |
Documents disk cache behavior/config and limitations. |
Cargo.toml |
Bumps version to 0.1.2 and adds dependencies (sha2, hex, walkdir, tempfile dev). |
Cargo.lock |
Locks new dependencies and version bump. |
CHANGELOG.md |
Adds 0.1.2 entry and updates compare links. |
.gitignore |
Ignores local cache directory and test_config.toml. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
src/disk_cache.rs
Outdated
| if let Ok(metadata) = entry.metadata() { | ||
| if let Ok(accessed) = metadata.modified() { | ||
| files.push((entry.path().to_path_buf(), accessed)); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| // Sort by access time (oldest first) | ||
| files.sort_by_key(|(_, time)| *time); | ||
|
|
There was a problem hiding this comment.
Eviction is described as LRU, but enforce_size_limit sorts by metadata.modified() (write time) and get() does not update that timestamp. As written, eviction is effectively “oldest write first”, not LRU. Also, using mtime for both TTL expiry and LRU access tracking conflicts (touching on read would extend TTL). Consider storing explicit timestamps in the .meta file (e.g., created_at + last_access) and base TTL/LRU on the appropriate field.
There was a problem hiding this comment.
Fixed in commit 1d83a79. Now stores metadata as JSON with separate created_at (for TTL) and last_access (for LRU) timestamps. The get() method updates last_access on every read, and enforce_size_limit() sorts by last_access for true LRU eviction.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
- Fix LRU eviction to use last_access timestamp instead of mtime - Store metadata (content_type, created_at, last_access) as JSON - Fix temp file extensions to use proper .tmp suffix - Fix size accounting to include both data and metadata files - Add logging for disk cache write failures - Remove unused _max_item_size parameter from new_with_disk_cache - Use tokio::task::spawn_blocking for all blocking I/O operations - Add comprehensive tests for eviction, temp file handling, and LRU tracking Co-authored-by: GrassBlock1 <46253950+GrassBlock1@users.noreply.github.com>
- Add max_item_size field to ResponseCache struct - Restore max_item_size parameter to new_with_disk_cache() - Configure moka cache with weigher based on cached data size - Enforce max_item_size limit in put() method with warning log - Check size when promoting items from disk to memory cache - Fix test_disk_cache_eviction to account for metadata overhead (2KB max_size) - All tests passing (29/29) Co-authored-by: GrassBlock1 <46253950+GrassBlock1@users.noreply.github.com>
Implementation Plan
config.rsdisk_cache.rsmodule with comprehensive implementationCargo.tomlSummary of Changes
Fixed all issues identified in code review:
LRU Eviction: Now properly tracks
created_at(for TTL) andlast_access(for LRU) separately in JSON metadata. Updates last_access on every read.Size Accounting: Fixed to include both data and metadata files in size calculations. Eviction now properly subtracts the size of both files.
Disk Write Logging: Added
warn!logging for disk cache write failures instead of silently ignoring them.Size-Based Cache Enforcement: Uses
max_item_sizeparameter to enforce size-based limits consistently in ResponseCache:put()method with warning log when exceededTest Coverage: Added 3 new tests:
test_disk_cache_eviction: Verifies size limit enforcementtest_disk_cache_ignores_temp_files: Ensures temp files aren't countedtest_disk_cache_lru_access_tracking: Validates true LRU behaviorAsync I/O: All blocking filesystem operations now wrapped in
tokio::task::spawn_blockingto prevent blocking the async runtime.Temp Files: Fixed to use proper
.tmpextension (e.g.,filename.tmp) instead of compound extensions.All tests passing (29/29).
Original prompt
💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.