Skip to content

fix: cache intrinsic APY aggregation by chain - #866

Merged
Seranged merged 2 commits into
developmentfrom
fix/lite-335
Sep 14, 2026
Merged

Seranged merged 2 commits into
developmentfrom
fix/lite-335

Conversation

@Seranged

@Seranged Seranged commented Sep 11, 2026

Copy link
Copy Markdown
Contributor

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

  • Tests verify caching despite different ignored query parameters, expiration at five minutes, concurrent request coalescing, and separation between chains.
  • Additional checks cover HEAD, unsupported chains, retry after an upstream rejection, nonempty cross-chain result isolation, and caching of HyperEVM all-source failure results until the origin TTL expires.
  • Node 24: lint (six existing warnings), typecheck, production build, and all 2,172 tests passed.
  • No production load test. Cache and deduplication are per server process, not shared across replicas. Partial or empty successful results use the same five-minute TTL.

Summary by CodeRabbit

  • Performance

    • Improved intrinsic APY retrieval with short-term caching.
    • Reduced duplicate upstream requests during concurrent access.
  • Reliability

    • Preserved retry behavior after failed upstream requests.
    • Continued appropriate handling for unsupported chains and HEAD requests.
  • Tests

    • Added coverage for cache expiration, chain-specific caching, concurrent requests, query parameters, and failure recovery.

Reuse five-minute origin results and coalesce concurrent requests independently of extra URL query parameters.
@railway-app
railway-app Bot temporarily deployed to euler-lite(dev,PR previews) / euler-lite-pr-866 September 11, 2026 12:06 Destroyed
@railway-app

railway-app Bot commented Sep 11, 2026

Copy link
Copy Markdown

🚅 Deployed to the euler-lite-pr-866 environment in euler-lite(dev,PR previews)

Service Status Web Updated
dev-build ✅ Success (View Logs) Web Sep 11, 2026 at 1:07 pm UTC

@coderabbitai

coderabbitai Bot commented Sep 11, 2026

Copy link
Copy Markdown

Review Change StackReview Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository: euler-xyz/coderabbit/.coderabbit.yaml

Review profile: CHILL

Plan: Essentials

Run ID: 9929f987-59df-4657-a78f-6d74d5d176bc

📥 Commits

Reviewing files that changed from the base of the PR and between 1474924 and 2ef3659.

📒 Files selected for processing (1)
  • tests/server/intrinsic-apy-overrides.test.ts

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.


📝 Walkthrough

Walkthrough

The 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.

Changes

Intrinsic APY caching

Layer / File(s) Summary
Cache-backed APY fetch flow
server/api/internal/proxy/intrinsic-apy-overrides.get.ts, tests/server/intrinsic-apy-overrides.test.ts
The handler caches supported chain responses, reuses in-flight requests by chain ID, and clears settled requests. Tests validate expiration, chain separation, concurrent requests, request filtering, failure caching, and retry behavior.

Priority: ⬇️ Low

Estimated code review effort: 2 (Simple) | ~12 minutes

Change: Bug fix

Suggested reviewers: leonardeulerxyz

Merge Risk: ⚪ Minimal · up to 2ef36

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)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 2…
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: caching intrinsic APY aggregation by chain.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/lite-335

Comment @coderabbitai help to get the list of available commands.

@LeonardEulerXYZ LeonardEulerXYZ left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.
@railway-app
railway-app Bot temporarily deployed to euler-lite(dev,PR previews) / euler-lite-pr-866 September 11, 2026 13:05 Destroyed

@LeonardEulerXYZ LeonardEulerXYZ left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@Seranged
Seranged merged commit bd50cc3 into development Sep 14, 2026
6 checks passed
@Seranged
Seranged deleted the fix/lite-335 branch September 14, 2026 10:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants