jenwitteng opened a new pull request, #42157:
URL: https://github.com/apache/superset/pull/42157
### SUMMARY
With `GLOBAL_ASYNC_QUERIES` enabled, uncached chart-data requests return
**HTTP 202** with job metadata (`channel_id`, `job_id`, `result_url`) rather
than inline results. Every Matrixify grid cell renders through `StatefulChart`
(`@superset-ui/core`), which previously treated that 202 body as chart data —
so each cell showed **"No data"** until a manual refresh warmed the cache.
`StatefulChart` now detects a 202 and delegates to an injected
`handleAsyncChartData` hook, which polls the async event channel and resolves
the cached results. The handler is wired in from `ChartRenderer` (reusing the
existing `handleChartDataResponse` / `waitForAsyncData`) and flows through the
standard hooks chain, keeping `superset-ui-core` decoupled from app-level
async-event middleware. If a 202 arrives with no handler, `StatefulChart` fails
loudly instead of silently rendering empty data.
Because a matrix fires many concurrent per-cell requests that can be
superseded by filter/formData changes and unmounted by scrolling, the change
also hardens the async lifecycle:
- **Correct response shapes** — the legacy endpoint's flat 202 body is
wrapped as `{ result: [body] }` to match the V1 signature the async handler
expects (legacy async previously received `undefined`); V1 bodies pass through
unchanged.
- **Supersession guards** — each request captures its own `AbortController`;
a late sync/async result or error is discarded if a newer request has
superseded it, so stale data can't overwrite fresh chart data.
- **Cancellation & no leaks** — `waitForAsyncData` accepts an `AbortSignal`,
removes its event listener on abort/unmount (no leaked listeners keeping the
poller busy), and cancels the in-flight cached-result download when aborted
mid-fetch.
- **Latest props on refetch** — `fetchData` reads current props via a ref
(it's memoized with an empty dep list), so updated filters/formData are used on
refetch.
- **Render-only changes preserved** — resolving an older async request
renders with the latest formData, so color/zoom changes aren't reverted.
- **Detailed error messages** — array-shaped `waitForAsyncData` rejections
are unwrapped so the parsed client-error message survives instead of collapsing
to a generic "An error occurred".
This supersedes #42033, which was built from a `master` snapshot that
predated the `Map`-based `listenersByJobId`/`retriesByJobId` refactor in
#40747; rebasing surfaced that mismatch (flagged by review as a `Record`
prototype-pollution regression) along with two other guards
(stale-response/stale-failure dedup and the per-result warning toast in
`exploreJSON`) that were dropped in the original diff. All three are restored
here, and the branch is rebased onto current `master`.
### BEFORE/AFTER SCREENSHOTS OR ANIMATED GIF
**BEFORE:** Matrixify cells show "No data" on first load when cache is cold.
<img width="1676" height="595" alt="Screenshot before"
src="https://github.com/user-attachments/assets/c8cc7c32-cfff-47fa-934f-6bf4890d47c6"
/>
**AFTER:** Cells show loading state, then resolve and render charts without
requiring a manual refresh.
<img width="1684" height="727" alt="Screenshot after"
src="https://github.com/user-attachments/assets/3c399c72-8c32-46e1-b18c-1b3cab77c2c8"
/>
### TESTING INSTRUCTIONS
1. Enable `GLOBAL_ASYNC_QUERIES` (and its required Celery worker +
cache/results backend + websocket/polling config)
2. Open a dashboard containing a Matrixify chart whose per-cell queries are
**not** already cached (clear cache or use `force`)
3. Verify cells show a loading state, then resolve and render each chart on
first load (not "No data")
4. Verify a **legacy-API** viz (e.g. deck.gl / world map / country map) in a
matrix cell also resolves
5. Rapidly change a dashboard filter while cells are still resolving —
confirm cells settle on the **latest** filter's data (no stale overwrite) and
no console errors/leaked listeners
6. Scroll a large matrix so cells unmount mid-load — confirm no "setState on
unmounted component" warnings and pending downloads are cancelled
7. Run automated tests:
```bash
cd superset-frontend
npm run test -- StatefulChart.test.tsx
npm run test -- asyncEvent.test.ts
npm run test -- chartActions.test.ts
npm run test -- ChartRenderer.test.tsx
```
### ADDITIONAL INFORMATION
- [ ] Has associated issue:
- [x] Required feature flags: `GLOBAL_ASYNC_QUERIES` (behavior only differs
when enabled; unchanged when off)
- [ ] Changes UI
- [ ] Includes DB Migration (follow approval process in
[SIP-59](https://github.com/apache/superset/issues/13351))
- [ ] Migration is atomic, supports rollback & is backwards-compatible
- [ ] Confirm DB migration upgrade and downgrade tested
- [ ] Runtime estimates and downtime expectations provided
- [ ] Introduces new feature or API
- [ ] Removes existing feature or API
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]