fix: cache intrinsic APY aggregation by chain - #866
Conversation
Reuse five-minute origin results and coalesce concurrent requests independently of extra URL query parameters.
|
🚅 Deployed to the euler-lite-pr-866 environment in euler-lite(dev,PR previews)
|
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository: euler-xyz/coderabbit/.coderabbit.yaml Review profile: CHILL Plan: Essentials Run ID: 📒 Files selected for processing (1)
Included review availability: 1 review is currently available. Your included PR review attempts over the past 7 days set your current allowance at 5 reviews per hour. 📝 WalkthroughWalkthroughThe intrinsic APY handler adds five-minute caching and concurrent request deduplication for chains 143 and 999. Tests cover cache isolation, expiry, request coalescing, unsupported requests, failure caching, and retry behavior. ChangesIntrinsic APY caching
Priority: ⬇️ Low Estimated code review effort: 2 (Simple) | ~12 minutes Change: Bug fix Suggested reviewers: Merge Risk: ⚪ Minimal · up to The added coverage aligns with the cache and request-deduplication behavior, with no remaining merge-blocking risk identified. 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
LeonardEulerXYZ
left a comment
There was a problem hiding this comment.
APY caching review — approved
Reviewed 147492444df8eb882c52c5db771a6010934a2a67: both changed files, TTL/fetch helpers, CDN configuration and Yuzu consumer. No blocking correctness findings.
- Chain isolation: only 143/999 enter the cache; results and pending work use normalized chain IDs. Distinct nonempty cross-chain fixtures passed.
- Expiry: TTL starts on completion and expires at age >= 300,000ms. Tested last fresh millisecond, exact expiry and concurrent refresh.
- Concurrency: same-chain work coalesces; separate chains remain independent. Finally clears pending work on success/rejection.
- Failures: Monad rejection is not cached; concurrent waiters reject and the next request retries. HyperEVM catches individual failures, so partial results (even all-failed empty arrays) are cached for five minutes. This matches the stated partial-result scope; immediate retry after rejection does not describe HyperEVM source failures.
- Query parameters: ignored parameters cannot create separate origin entries/work. Rate limiting remains per request; HEAD/unsupported chains do not fetch.
Non-blocking follow-ups: commit nonempty chain-isolation and HyperEVM failure fixtures (existing tests mostly assert counts on empty data). Five minutes is an origin TTL, not an end-to-end freshness bound: existing CDN/SWR and client caches can extend visible age. Deduplication is per process, not replica-wide.
Validation: Nuxt prepare; 12 tests passed across intrinsic-apy-overrides, shared cache and Yuzu consumer suites; four extra scratch discriminators passed (nonempty concurrent chains, completion-based expiry/coalescing, shared rejection/retry, HyperEVM all-failed caching); targeted ESLint, typecheck and production build passed locally on Node 26.5.1. GitHub lint/typecheck/test/preview-build checks are successful. No production load test or live upstream-value validation. Deterministic fixtures use actual pool IDs from the route. No package/schema changes requiring coordinated cross-repo release. Scratch tests were not committed.
Exercise nonempty chain results and the documented HyperEVM all-failed caching behavior.
LeonardEulerXYZ
left a comment
There was a problem hiding this comment.
Approved at 2ef3659c5b5a76c1c0d43277374058e734ad2b57.
Verified the previous-head delta is test-only and rechecked the full two-file PR diff. The new tests cover distinct nonempty results across concurrent chains (including subsequent cache hits) and HyperEVM all-source failures cached until exact TTL expiry. This addresses the regression-fixture follow-up; runtime behavior is unchanged and no new blockers were found.
Validation: 18 tests passed across the three committed focused suites plus four retained scratch discriminators; targeted ESLint and full typecheck passed. Production build passed on the previous head; not rerun for this test-only delta. The previously noted per-process and layered-cache freshness boundaries remain unchanged.
Issue
Each origin GET for chain 999 starts eight upstream requests, including downloading and parsing the full DefiLlama pools dataset. Chain 143 makes one upstream request for that dataset. Without an origin cache or in-flight deduplication, repeated or concurrent requests repeat this work.
Browser/CDN cache headers alone do not bound origin aggregation work. Different URLs containing ignored query parameters can select the same chain while occupying different edge cache entries, consuming upstream request capacity, bandwidth, and parsing resources.
Resolution
Cache aggregation results for five minutes per normalized chain ID and share a single in-flight aggregation for concurrent requests to that chain. Additional query parameters do not affect either key. The cache is bounded to the two supported chains, 999 and 143.
Each request still passes through the rate limiter. HEAD and unsupported-chain requests avoid aggregation. Completed results retain the existing partial-result behavior; rejected aggregations clear their in-flight entry so a subsequent request can retry.
Validation
Summary by CodeRabbit
Performance
Reliability
Tests