feat(cache): make cached decorator async-aware#167
Conversation
- Share concurrent async decorator calls with single-flight behavior - Avoid caching rejected promises so later calls can retry - Document async decorator usage and normalize docs SEO descriptions Closes #162
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
✅ Files skipped from review due to trivial changes (2)
📝 WalkthroughWalkthroughThe ChangesAsync-aware
Sequence Diagram(s)sequenceDiagram
participant Caller
participant CachedDecorator
participant InFlightMap
participant MemoryCache
participant UnderlyingMethod
Caller->>CachedDecorator: call(key)
CachedDecorator->>MemoryCache: lookup(key)
alt hit and key is async
MemoryCache-->>CachedDecorator: value
CachedDecorator->>Caller: Promise.resolve(value)
else miss
CachedDecorator->>InFlightMap: has(key)?
alt exists
InFlightMap-->>CachedDecorator: existing promise
CachedDecorator->>Caller: existing promise
else not exists
CachedDecorator->>UnderlyingMethod: invoke()
UnderlyingMethod-->>CachedDecorator: Promise
CachedDecorator->>InFlightMap: store promise
CachedDecorator->>Caller: promise
UnderlyingMethod->>CachedDecorator: resolve(value) / reject(error)
alt resolved
CachedDecorator->>MemoryCache: store resolved value
CachedDecorator->>CachedDecorator: mark asyncKey
CachedDecorator->>InFlightMap: remove(key)
CachedDecorator->>Caller: resolved value
else rejected
CachedDecorator->>InFlightMap: remove(key)
CachedDecorator->>Caller: propagate rejection (not cached)
end
end
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Suggested labels
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
src/cache.ts (1)
161-162: 💤 Low valueRedundant type alias.
PromiseLikeValue<T>is identical to the built-inPromiseLike<T>. Consider usingPromiseLike<T>directly inisPromiseLiketo reduce indirection.🤖 Prompt for 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. In `@src/cache.ts` around lines 161 - 162, Remove the redundant type alias PromiseLikeValue<T> and use the built-in PromiseLike<T> directly in the isPromiseLike utility: replace references to PromiseLikeValue<T> with PromiseLike<T>, delete the PromiseLikeValue declaration, and update the isPromiseLike function signature/usage to reference PromiseLike so there is no unnecessary indirection.
🤖 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.
Nitpick comments:
In `@src/cache.ts`:
- Around line 161-162: Remove the redundant type alias PromiseLikeValue<T> and
use the built-in PromiseLike<T> directly in the isPromiseLike utility: replace
references to PromiseLikeValue<T> with PromiseLike<T>, delete the
PromiseLikeValue declaration, and update the isPromiseLike function
signature/usage to reference PromiseLike so there is no unnecessary indirection.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 511aa0f2-7540-4224-a9e6-07d098672fe5
📒 Files selected for processing (18)
README.mddocs/src/lib/docsNav.tsdocs/src/routes/docs/api/cached-decorator/+page.svxdocs/src/routes/docs/examples/+page.sveltedocs/src/routes/docs/examples/api-caching/+page.svxdocs/src/routes/docs/examples/async-decorator/+page.svxdocs/src/routes/docs/examples/async-decorator/+page.tsdocs/src/routes/docs/examples/async-fetching/+page.svxdocs/src/routes/docs/examples/computed-values/+page.svxdocs/src/routes/docs/examples/configuration/+page.svxdocs/src/routes/docs/examples/database-caching/+page.svxdocs/src/routes/docs/examples/monitoring/+page.svxdocs/src/routes/docs/examples/multi-tenant/+page.svxdocs/src/routes/docs/examples/rate-limiting/+page.svxdocs/src/routes/docs/examples/service-class/+page.svxdocs/src/routes/docs/examples/sessions/+page.svxsrc/cache.decorator.test.tssrc/cache.ts
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 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 `@docs/src/routes/docs/examples/sessions/`+page.svx:
- Line 3: Update the description text that currently calls
"`@humanspeak/memory-cache`" a "lightweight Redis alternative" to avoid implying
feature parity with Redis; change the phrasing to accurately describe the
library's behavior (for example: "lightweight in-memory session store" or
"simple TTL-based session cache") wherever that description appears (see the
description line and any repeated instances around lines referencing
`@humanspeak/memory-cache` in +page.svx) so the docs correctly convey it is an
in-process TTL cache, not a distributed Redis replacement.
🪄 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: CHILL
Plan: Pro
Run ID: 1bcf37a3-703b-473e-8912-2a5e531b6f1a
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml,!pnpm-lock.yaml
📒 Files selected for processing (42)
docs/package.jsondocs/src/lib/docs-config.tsdocs/src/routes/+page.tsdocs/src/routes/docs/api/cached-decorator/+page.svxdocs/src/routes/docs/api/cached-decorator/+page.tsdocs/src/routes/docs/api/memory-cache/+page.svxdocs/src/routes/docs/api/memory-cache/+page.tsdocs/src/routes/docs/examples/+page.tsdocs/src/routes/docs/examples/api-caching/+page.svxdocs/src/routes/docs/examples/api-caching/+page.tsdocs/src/routes/docs/examples/async-decorator/+page.svxdocs/src/routes/docs/examples/async-decorator/+page.tsdocs/src/routes/docs/examples/async-fetching/+page.svxdocs/src/routes/docs/examples/async-fetching/+page.tsdocs/src/routes/docs/examples/computed-values/+page.svxdocs/src/routes/docs/examples/computed-values/+page.tsdocs/src/routes/docs/examples/configuration/+page.svxdocs/src/routes/docs/examples/configuration/+page.tsdocs/src/routes/docs/examples/database-caching/+page.svxdocs/src/routes/docs/examples/database-caching/+page.tsdocs/src/routes/docs/examples/monitoring/+page.svxdocs/src/routes/docs/examples/monitoring/+page.tsdocs/src/routes/docs/examples/multi-tenant/+page.svxdocs/src/routes/docs/examples/multi-tenant/+page.tsdocs/src/routes/docs/examples/rate-limiting/+page.svxdocs/src/routes/docs/examples/rate-limiting/+page.tsdocs/src/routes/docs/examples/service-class/+page.svxdocs/src/routes/docs/examples/service-class/+page.tsdocs/src/routes/docs/examples/sessions/+page.svxdocs/src/routes/docs/examples/sessions/+page.tsdocs/src/routes/docs/getting-started/+page.svxdocs/src/routes/docs/getting-started/+page.tsdocs/src/routes/examples/+page.sveltedocs/src/routes/examples/+page.tsdocs/src/routes/examples/basic-cache/+page.sveltedocs/src/routes/examples/basic-cache/+page.tsdocs/src/routes/examples/cache-statistics/+page.sveltedocs/src/routes/examples/cache-statistics/+page.tsdocs/src/routes/examples/lru-eviction/+page.sveltedocs/src/routes/examples/lru-eviction/+page.tsdocs/src/routes/examples/ttl-expiration/+page.sveltedocs/src/routes/examples/ttl-expiration/+page.ts
✅ Files skipped from review due to trivial changes (32)
- docs/src/routes/docs/getting-started/+page.ts
- docs/src/routes/docs/examples/monitoring/+page.ts
- docs/src/routes/docs/examples/sessions/+page.ts
- docs/src/routes/examples/lru-eviction/+page.ts
- docs/src/routes/examples/+page.ts
- docs/src/routes/docs/examples/database-caching/+page.ts
- docs/src/routes/docs/api/memory-cache/+page.ts
- docs/package.json
- docs/src/routes/+page.ts
- docs/src/routes/examples/basic-cache/+page.ts
- docs/src/routes/docs/examples/+page.ts
- docs/src/routes/docs/examples/rate-limiting/+page.ts
- docs/src/routes/examples/ttl-expiration/+page.ts
- docs/src/routes/docs/examples/api-caching/+page.ts
- docs/src/routes/docs/examples/computed-values/+page.ts
- docs/src/routes/docs/examples/configuration/+page.ts
- docs/src/routes/docs/examples/async-fetching/+page.ts
- docs/src/routes/docs/api/cached-decorator/+page.ts
- docs/src/routes/docs/examples/multi-tenant/+page.ts
- docs/src/routes/docs/getting-started/+page.svx
- docs/src/routes/examples/cache-statistics/+page.ts
- docs/src/routes/docs/examples/service-class/+page.ts
- docs/src/lib/docs-config.ts
- docs/src/routes/docs/examples/service-class/+page.svx
- docs/src/routes/docs/examples/api-caching/+page.svx
- docs/src/routes/docs/examples/async-decorator/+page.ts
- docs/src/routes/docs/examples/multi-tenant/+page.svx
- docs/src/routes/docs/api/memory-cache/+page.svx
- docs/src/routes/docs/examples/computed-values/+page.svx
- docs/src/routes/docs/examples/monitoring/+page.svx
- docs/src/routes/docs/examples/async-fetching/+page.svx
- docs/src/routes/docs/api/cached-decorator/+page.svx
🚧 Files skipped from review as they are similar to previous changes (3)
- docs/src/routes/docs/examples/async-decorator/+page.svx
- docs/src/routes/docs/examples/configuration/+page.svx
- docs/src/routes/docs/examples/database-caching/+page.svx
|
Responding to your review comments:
|
|
Tip For best results, initiate chat on the files or code changes.
|
Summary
Adds async-aware behavior to the
@cacheddecorator so concurrent async method calls share one in-flight execution and rejected promises are not cached. This makes decorator memoization match the retry-safe single-flight semantics already available throughgetOrSet().Changes
✨ New features
@cachedmethod calls with identical arguments.🧪 Testing
📚 Documentation
seo.descriptionfields to the 110-160 character recommendation.Commits
fbe3212feat(cache): make cached decorator async-awareCloses #162