Skip to content

fix(rest-client): cache fetched catalog for the session - #65

Open
Akil-Dikshan wants to merge 1 commit into
wso2:mainfrom
Akil-Dikshan:fix/cache-fetched-catalog
Open

Akil-Dikshan wants to merge 1 commit into
wso2:mainfrom
Akil-Dikshan:fix/cache-fetched-catalog

Conversation

@Akil-Dikshan

Copy link
Copy Markdown
Contributor

Description

Every page click, sort change and re-render re-entered searchPackages with the same filters, and on the full-fetch path (which the default sort, pullCount-desc, already takes) each one re-ran the entire count + 500-item-batch fetch against Central just to slice a different page. This matched the reported "10-12s first load, ~26s for a deep-linked search, 3 Central requests per page click" behavior.

This adds a session cache for the full-fetch path's merged/deduped/filtered catalog, keyed by what actually changes Central's request (query, areas, vendors, types, orgName) — deliberately not by sort, offset or limit, which are applied in memory on every call. In-flight promises are cached too, so concurrent callers share one fetch, and a failed fetch evicts its own entry so the next call retries instead of reusing the failure.

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • Performance improvement

Related Issue(s)

Relates to wso2/product-integrator#<ISSUE_NUMBER>

Changes Made

  • Added a module-level cache (fetchedCatalogCache) following the existing rankingDataCache/hiddenCountCache pattern, with a 12-minute TTL.
  • Extracted the merge/dedup/excludeHidden/filterByExactKeywords/filterByRelevance logic from searchPackages into fetchCatalog, now called through getFetchedCatalog, which checks the cache before fetching.
  • The fetch itself is pinned to pullCount-desc sort, so cached order (which decides tie-breaking) doesn't depend on which sort happened to trigger the first fetch — sortMergedPackages still re-sorts a copy of the cached array on every call.
  • On a rejected fetch, the cache entry is evicted (only if it's still the same entry, to avoid a race with a newer fetch) and the error is rethrown — no silent empty-catalog fallback.
  • Added __resetFetchedCatalogCacheForTests(), called in beforeEach of rest-client.test.ts.
  • Cache key normalizes input: query is trimmed, and areas/vendors/types arrays are sorted before joining, so equivalent requests (reordered filters, padded whitespace) hit the same entry.

Known pre-existing issue, out of scope: getTotalHiddenCount's own cache never evicts on a rejected fetch, so a failed hidden-count fetch stays cached for the session. Not fixed here — flagging for a separate issue.

Testing Performed

Test Environment

  • Browser(s): N/A — verified via Jest with a mocked fetch, not a real browser
  • OS: Ubuntu
  • Node Version: 18.19.1

Test Cases

  • Unit tests pass (npm test) — 6 suites, 107 tests (baseline: 6 suites, 102 tests)
  • Integration tests pass (if applicable)
  • Manual testing completed
  • Tested on mobile devices
  • Tested on desktop browsers

New tests (describe block in rest-client.test.ts):

  • A page change with identical filters/sort adds zero Central requests.
  • A sort-only change adds zero Central requests and sorts in memory; a later call confirms the cache wasn't mutated by the sort.
  • Concurrent calls share one fetch (in-flight promise dedup).
  • A query or filter change does re-fetch; an equivalent key (trimmed query, reordered filter arrays) does not.
  • A failed fetch is retried on the next call rather than reusing the rejected promise.

All 18 existing rest-client.test.ts tests pass unchanged; only the import and a beforeEach reset call were added to that part of the file.

Screenshots

Before

Not applicable — this is a request-count/timing change, not a visual one.

After

Not applicable.

Code Quality Checklist

  • Code follows project style guidelines (npm run lint passes)
  • Code is properly formatted (npm run format:check passes)
  • TypeScript compilation succeeds (npx tsc --noEmit)
  • No console.log statements (except console.warn/console.error)
  • Comments added for complex logic
  • Self-review completed

Documentation

  • README updated (if needed)
  • CHANGELOG updated (if needed)
  • Documentation added/updated (if needed)
  • JSDoc comments added for new functions

Performance Impact

  • Performance improved

Details: Eliminates redundant full-catalog fetches from Central on every page click and sort change within a session. Real-world timing (the reported 10-12s/26s figures) hasn't been re-measured against Central after this change — flagging as a gap, not a claimed number.

Breaking Changes

  • No breaking changes

Additional Notes

  • Cache TTL (12 minutes) is a default — open to changing it.
  • The cached array is shared across callers; every consumer (sort, slice) operates on a copy, never the cached reference itself.
  • This PR is a dependency for fix/sort-full-catalog (3a), which widens which sorts trigger the full-fetch path — that PR is a draft until this one merges.

Reviewer Checklist

  • Code reviewed
  • Tests reviewed
  • Documentation reviewed
  • No security concerns
  • Approved

By submitting this pull request, I confirm that my contribution is made under the terms of the project's license.

@coderabbitai

coderabbitai Bot commented Oct 5, 2026

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 3d386512-e39c-4ed6-8c8a-bbca5183835e
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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

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.

1 participant