feat(cache/unstable): add sliding expiration to TtlCache#7046
feat(cache/unstable): add sliding expiration to TtlCache#7046bartlomieju merged 2 commits intodenoland:mainfrom
TtlCache#7046Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #7046 +/- ##
=======================================
Coverage 94.41% 94.41%
=======================================
Files 630 630
Lines 50435 50486 +51
Branches 8928 8946 +18
=======================================
+ Hits 47616 47666 +50
Misses 2249 2249
- Partials 570 571 +1 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
bartlomieju
left a comment
There was a problem hiding this comment.
The core feature (sliding expiration) is well-implemented and thoroughly tested. However, this PR bundles several breaking changes with a new feature. I'd recommend splitting it:
- One PR for the breaking cleanup (
set()options object,delete/clearbehavior, validation) - One PR for the sliding expiration feature on top
Some specific points:
Breaking change: set() signature
The positional ttl parameter is replaced by an options object. Even for an unstable API, this should be called out explicitly as a breaking change.
clear() behavior change
clear() now calls onEject for every entry (swallowing intermediate errors, re-throwing the first). Previously it didn't call onEject at all. This could surprise existing users whose onEject has side effects.
delete() call order change
onEject now fires after the entry is removed from the map (previously it fired before). The test "entry is fully removed before onEject fires" validates this, but it's a subtle breaking change for any onEject callback that inspects the cache.
has() resetting TTL is debatable
In many caching libraries, only get() resets the sliding timer. has() is typically a read-only probe — having it keep entries alive indefinitely could cause unexpected behavior.
Third type parameter ergonomics
TtlCache<string, number, true> is verbose. A factory method or subclass might be cleaner than the redundancy between the type parameter and constructor option.
absoluteExpiration silently ignored without slidingExpiration
Passing absoluteExpiration on a non-sliding cache is only a compile-time error. At runtime it's quietly ignored with no validation or warning.
Stale commits in history
The PR contains two unrelated commits (feat(http): stabilize ServerSentEventParseStream and its revert) that should be rebased out before merge.
06723bd to
e9efafe
Compare
|
Split out the breaking changes as requested: #7065 Once that is merged I will update this PR to build on it. |
When `slidingExpiration: true` is passed to the constructor, each `get()` call resets the entry's TTL. An optional per-entry `absoluteExpiration` caps how far the sliding window can extend. `has()` is a read-only probe and does not reset the TTL. Made-with: Cursor
e9efafe to
695be1d
Compare
|
Updated the PR, it now cleanly applies only the new sliding expiration feature |
|
The third type parameter const cache = new TtlCache<string, number, true>(100, {
slidingExpiration: true,
});TypeScript can't infer the class-level generic from the constructor options, so this redundancy is unavoidable with the current design. A few alternatives worth considering:
Any of these would keep the API at two type params, which is much more ergonomic. Since this is still unstable, now's the time to get the shape right. |
|
Agree, that makes a lot of sense. I decided for option 3 (dropping the type parameter) with runtime validation. |
|
Looks good, nice work! One minor nit for a follow-up: The Not blocking — happy to land this as-is and fix in a follow-up. |
|
Good catch. Sorry about that! Fix included here: #7070 |
…7046) Sliding expiration: entries can now stay alive as long as they're being accessed, with an optional hard deadline. Useful for sessions or rate-limit windows.
NOTE: Builds on #7065
Sliding expiration: entries can now stay alive as long as they're being accessed, with an optional hard deadline. Useful for sessions or rate-limit windows.