Skip to content

feat(server-core): bound refresh-key dispatch fan-out by concurrency per orchestrator id#11106

Draft
paveltiunov wants to merge 1 commit into
masterfrom
cursor/refresh-scheduler-refresh-key-concurrency-2a86
Draft

feat(server-core): bound refresh-key dispatch fan-out by concurrency per orchestrator id#11106
paveltiunov wants to merge 1 commit into
masterfrom
cursor/refresh-scheduler-refresh-key-concurrency-2a86

Conversation

@paveltiunov

Copy link
Copy Markdown
Member

Summary

The scheduled refresh dispatches all refresh-key queries simultaneously with no concurrency cap at the dispatch level. RefreshScheduler.refreshCubesRefreshKey fans out with nested Promise.all — over cubes, and within each cube over timezones — without any pLimit or throttle. The concurrency/workerIndices in ScheduledRefreshQueryingOptions were only consumed by refreshPreAggregations (the round-robin worker iterator), not by refreshCubesRefreshKey.

While the database is still effectively bounded downstream (per-datasource QueryQueue concurrency, @AsyncDebounce() on loadRefreshKey, and renewal-threshold/in-memory caching), the dispatch itself creates a large promise fan-out in Node for deployments with many cubes/timezones — i.e. memory and event-loop pressure.

This PR adds a pLimit in refreshCubesRefreshKey to bound the dispatch fan-out, using the scheduler concurrency (which is derived per orchestrator from the minimum queue concurrency). The limiter is shared per orchestrator id, so concurrent scheduled refresh runs that resolve to the same orchestrator (e.g. multiple security contexts) respect a single cap rather than each flooding the event loop independently.

Changes

  • server.ts: add getRefreshKeysLimiter(context, concurrency) which returns a pLimit instance cached per orchestrator id (rebuilt only when the concurrency value changes). The cache lives on the long-lived CubejsServerCore so it persists across short-lived RefreshScheduler instances.
  • RefreshScheduler.ts: wrap each refresh-key executeQuery dispatch (and its getSql) in the shared limiter so no more than concurrency refresh-key queries are dispatched at once per orchestrator.

Tests

  • getRefreshKeysLimiter returns a shared limiter per orchestrator id — verifies the limiter is reused for the same orchestrator id + concurrency and rebuilt when concurrency changes.
  • Refresh key dispatch is bounded by concurrency — instruments the orchestrator's executeQuery to track in-flight loadRefreshKeysOnly dispatches across multiple cubes/timezones and asserts the peak concurrency never exceeds the configured value.

All 15 tests in RefreshScheduler.test.ts pass; tsc build and ESLint are clean.

Open in Web Open in Cursor 

…per orchestrator id

Co-authored-by: Pavel Tiunov <pavel.tiunov@gmail.com>
@github-actions github-actions Bot added the javascript Pull requests that update Javascript code label Jun 17, 2026
@codecov

codecov Bot commented Jun 17, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 58.53%. Comparing base (28c6938) to head (ab37198).
⚠️ Report is 1 commits behind head on master.

❗ There is a different number of reports uploaded between BASE (28c6938) and HEAD (ab37198). Click for more details.

HEAD has 1 upload less than BASE
Flag BASE (28c6938) HEAD (ab37198)
cubesql 1 0
Additional details and impacted files
@@             Coverage Diff             @@
##           master   #11106       +/-   ##
===========================================
- Coverage   83.61%   58.53%   -25.09%     
===========================================
  Files         256      216       -40     
  Lines       78904    17284    -61620     
  Branches        0     3525     +3525     
===========================================
- Hits        65975    10117    -55858     
+ Misses      12929     6652     -6277     
- Partials        0      515      +515     
Flag Coverage Δ
cube-backend 58.53% <100.00%> (?)
cubesql ?

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

javascript Pull requests that update Javascript code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants