🧹 chore: Improve Cache middleware defaults#3740
Conversation
|
Note Other AI code review bot(s) detectedCodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review. WalkthroughRenames CacheControl to DisableCacheControl in the cache middleware Config, changes default Expiration to 5m and MaxBytes to 1 MiB, updates docs and tests to match, replaces a busy-wait timestamp loop with a ticker, and adds tests for Cache-Control emission/omission. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant App as App
participant MW as CacheMiddleware
participant Store as CacheStorage
participant Ticker as TimestampTicker
rect #E8F0FF
note right of MW: Initialization (changed)
App->>MW: Initialize middleware
MW->>Ticker: time.NewTicker(timestampUpdatePeriod)
Ticker-->>MW: tick events on ticker.C
MW->>MW: update internal timestamp on tick
end
rect #F0FFF0
note right of MW: Request handling (Cache-Control conditional)
App->>MW: HTTP Request
MW->>Store: Lookup(key)
alt Hit
Store-->>MW: Cached response
MW-->>App: Return cached response (sets Cache-Control if !cfg.DisableCacheControl)
else Miss
MW->>App: Call next handler
App-->>MW: Response
MW->>Store: Store response (respect MaxBytes)
MW-->>App: Return response (sets Cache-Control if !cfg.DisableCacheControl)
end
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Suggested reviewers
Pre-merge checks (1 passed, 2 warnings)❌ Failed checks (2 warnings)
✅ Passed checks (1 passed)
Poem
📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: CHILL Plan: Pro 📒 Files selected for processing (4)
🧰 Additional context used📓 Path-based instructions (2)**/*.go📄 CodeRabbit inference engine (AGENTS.md)
Files:
docs/**📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Files:
🧠 Learnings (1)📚 Learning: 2024-10-08T19:06:06.583ZApplied to files:
🧬 Code graph analysis (1)middleware/cache/cache_test.go (2)
⏰ 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). (4)
🔇 Additional comments (14)
✨ Finishing touches
🧪 Generate unit tests
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. Comment |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #3740 +/- ##
=======================================
Coverage 92.02% 92.02%
=======================================
Files 115 115
Lines 11585 11586 +1
=======================================
+ Hits 10661 10662 +1
Misses 670 670
Partials 254 254
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request improves the default configuration for the cache middleware by enabling CacheControl by default, increasing the default expiration time to 5 minutes, and setting a default MaxBytes limit of 1MB. It also correctly replaces time.Sleep with a time.Ticker for timestamp updates to prevent time drift. The code changes and test updates are solid. I've found a significant issue in the documentation where two configuration options were accidentally removed from the configuration table, and I've also noted some formatting issues in the same table, for which I've provided a suggestion.
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (3)
middleware/cache/config.go (2)
62-69: Defaults for MaxBytes and CacheControl: code vs. runtime behavior mismatchYou updated comments/defaults to 1 MiB and true, but configDefault(...) does not populate these when a partial Config literal is passed (common usage). That means:
- New() → CacheControl=true, MaxBytes=1MiB
- New(Config{...}) (omit) → CacheControl=false, MaxBytes=0 (unlimited)
This is surprising given the docs. Two options:
- Short term (docs): clearly document that omitted fields in a provided literal take Go zero-values and must be explicitly set to match defaults.
- Long term (API): consider tri-state config (e.g., CacheControl *bool, MaxBytes *uint) or a sentinel for unlimited to let configDefault apply real defaults without breaking explicit false/0.
If you want, I can draft a non-breaking docs note now and an RFC for tri-state in v3.
101-121: configDefault doesn’t apply new defaults to MaxBytes/CacheControlConsider whether you want defaults to apply when users pass a partial Config. If yes, you’ll need a tri-state approach for bool/uint (breaking) or companion flags (e.g., MaxBytesUnlimited bool) to preserve “0 means unlimited” while still defaulting to 1 MiB when omitted. Otherwise, add a prominent doc note (see docs comment).
middleware/cache/cache.go (1)
93-96: Ticker-based timestamp updater — LGTM; consider lifecycleUsing time.Ticker avoids drift. Minor: the goroutine has no shutdown path, so defer ticker.Stop() won’t run. Optional: tie ticker to app lifecycle or a done channel for clean shutdowns in long-lived tests.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
docs/middleware/cache.md(2 hunks)middleware/cache/cache.go(1 hunks)middleware/cache/cache_test.go(7 hunks)middleware/cache/config.go(2 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.go
📄 CodeRabbit inference engine (AGENTS.md)
**/*.go: Format Go code using gofumpt (enforced viamake format)
Ensure code passes golangci-lint checks (enforced viamake lint)
Optimize struct field alignment using betteralign (enforced viamake betteralign)
Modernize Go code using gopls modernize (enforced viamake modernize)
Files:
middleware/cache/config.gomiddleware/cache/cache_test.gomiddleware/cache/cache.go
docs/**
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Review and update the contents of the
docsfolder if necessary when modifying code
Files:
docs/middleware/cache.md
🧬 Code graph analysis (2)
middleware/cache/config.go (2)
internal/memory/memory.go (1)
Storage(12-15)internal/storage/memory/memory.go (1)
Storage(14-19)
middleware/cache/cache_test.go (1)
middleware/cache/config.go (1)
Config(11-75)
⏰ 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: Compare
- GitHub Check: repeated
🔇 Additional comments (13)
middleware/cache/cache_test.go (7)
31-31: Good test improvement!Moving
CacheControl: trueto the end ensures the test focuses on the core functionality while maintaining proper field ordering.
46-66: Excellent test coverage for disabled CacheControl!This new test ensures that when
CacheControl: falseis set, noCache-Controlheader is emitted. This validates the correct behavior when users explicitly disable client-side caching.
366-366: LGTM!The test properly uses only the
Expirationfield, which is appropriate since the defaultCacheControl: truefrom the updated defaults will be used.
819-819: LGTM!The field reordering maintains consistency across tests while preserving the intended behavior.
875-876: LGTM!The field reordering is consistent with the overall improvements and maintains test functionality.
911-911: LGTM!The field placement maintains consistency across the test suite.
1160-1160: LGTM!The config correctly uses explicit field values, which is appropriate for this test that needs to control specific behavior.
middleware/cache/config.go (2)
55-56: Default Expiration: 5m — LGTMDoc + default value align and are reasonable for typical cache workloads.
80-92: ConfigDefault updates — LGTM, but ensure tests cover “partial config” edgeValues match the new policy. Please add/adjust tests to assert:
- New() uses CacheControl=true, MaxBytes=1MiB
- New(Config{Expiration: X}) keeps CacheControl=false and MaxBytes=0 unless explicitly set
This makes the behavior explicit and prevents regressions.docs/middleware/cache.md (2)
9-10: Top-level defaults text — LGTMMatches code: 5 minutes and ~1 MB.
124-139: Default Config snippet — LGTMMatches middleware/cache/config.go.
middleware/cache/cache.go (2)
168-171: Cache-Control emission logic — LGTMHeader is set only on hits, only when enabled, and only if not already present; preserves server intent.
269-279: Expiration/TTL math — LGTMSeconds precision with periodic timestamp refresh is consistent with max-age/Age semantics.
There was a problem hiding this comment.
Pull Request Overview
This PR improves the Cache middleware defaults to provide better out-of-the-box performance and behavior for caching functionality in Fiber applications.
- Enable CacheControl by default to provide client-side caching headers
- Increase default timeout from 1 minute to 5 minutes for longer cache retention
- Set default MaxBytes to 64MB to prevent unbounded memory usage
- Replace sleep-based timestamp updates with time.Ticker to prevent time drift
Reviewed Changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 6 comments.
| File | Description |
|---|---|
| middleware/cache/config.go | Updates default configuration values for expiration, CacheControl, and MaxBytes |
| middleware/cache/cache_test.go | Adds test for disabled CacheControl and updates existing tests to reflect new defaults |
| middleware/cache/cache.go | Replaces sleep loop with time.Ticker for timestamp updates |
| docs/middleware/cache.md | Updates documentation to reflect new default values and adds description of default behavior |
There was a problem hiding this comment.
Actionable comments posted: 0
♻️ Duplicate comments (1)
docs/middleware/cache.md (1)
112-116: Defaults update looks correct; missing prior omissions are now coveredExpiration=5m and CacheControl=true reflected; KeyGenerator and CacheInvalidator rows restored. Nice.
🧹 Nitpick comments (4)
docs/middleware/cache.md (4)
9-10: Unify size unit (1 MiB) for consistency with defaultsTop note says “1 MB” while the table uses
1 * 1024 * 1024 (~1 MB). Recommend “1 MiB (~1 MB)” to avoid ambiguity.-By default, cached responses expire after five minutes and the middleware stores up to 1 MB of response bodies. +By default, cached responses expire after five minutes and the middleware stores up to 1 MiB (~1 MB) of response bodies.
109-122: Add a note about zero-values when passing partial Config literalsReaders may assume documented defaults apply when only some fields are set. Clarify that omitted fields take Go zero-values.
| Methods | `[]string` | Methods specifies the HTTP methods to cache. | `[]string{fiber.MethodGet, fiber.MethodHead}` | | +> Note: When passing a partial `cache.Config` literal to `cache.New(...)`, omitted fields take Go zero-values +> (e.g., `CacheControl` becomes `false`, `MaxBytes` becomes `0`). To keep the documented defaults while +> customizing, either set them explicitly (e.g., `CacheControl: true`, `MaxBytes: 1*1024*1024`) or start from +> `cfg := cache.ConfigDefault` and override only what you need.
114-114: Specify exact header semantics for CacheControl=trueDocument what header is emitted (e.g., “Cache-Control: public, max-age=”) and how its value relates to
Expiration/ExpirationGenerator.-| CacheControl | `bool` | CacheControl enables client-side caching if set to true. Set to `false` to omit the `Cache-Control` header. | `true` | +| CacheControl | `bool` | When `true`, emits a `Cache-Control` response header (max-age equals the effective expiration). Set to `false` to omit the header. | `true` |
120-120: Clarify behavior whenMaxBytesis reachedDoes the middleware evict entries (LRU/size-based) or skip writing new ones? Add one sentence describing the policy.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
docs/middleware/cache.md(2 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
docs/**
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Review and update the contents of the
docsfolder if necessary when modifying code
Files:
docs/middleware/cache.md
🧠 Learnings (1)
📚 Learning: 2024-10-08T19:06:06.583Z
Learnt from: hcancelik
PR: gofiber/fiber#3036
File: docs/middleware/cache.md:103-103
Timestamp: 2024-10-08T19:06:06.583Z
Learning: There are no hard tabs in the lines 100 to 105 of the `docs/middleware/cache.md` file. Future comments about formatting should accurately reflect the actual content.
Applied to files:
docs/middleware/cache.md
⏰ 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). (6)
- GitHub Check: Analyse
- GitHub Check: unit (1.25.x, macos-latest)
- GitHub Check: unit (1.25.x, windows-latest)
- GitHub Check: unit (1.25.x, macos-13)
- GitHub Check: repeated
- GitHub Check: Compare
🔇 Additional comments (1)
docs/middleware/cache.md (1)
128-139: Default Config snippet aligns with stated defaultsValues for
Expiration,CacheControl, andMaxBytesmatch the table and summary.
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request introduces sensible improvements to the cache middleware's default settings, such as enabling CacheControl by default, increasing the expiration time, and setting a MaxBytes limit. The switch from time.Sleep to time.Ticker is a great enhancement for accuracy. The changes are well-reflected in the documentation and tests. I have one minor suggestion to improve the documentation's formatting.
* Make CacheControl boolean * docs(cache): align defaults with config * Limit cache entries to 1MB and restore docs * Rename cache control option
Summary
Replaced #3726