villebro opened a new pull request, #43794:
URL: https://github.com/apache/superset/pull/43794

   ### SUMMARY
   
   Two follow-ups from an external review of the async chart-data / websocket 
work on the `gaq-to-gtf` epic (#43407). Both are correctness fixes on the 
frontend; no backend or schema changes.
   
   **1. Forced async read-back dropped `force` and the per-query nonce 
(`StatefulChart`).**
   The HTTP 202 async path in the `@apache-superset/core` package 
(`StatefulChart`, used by Matrixify) re-issued the `/chart/data` POST with a 
bare `refetch()` — no `force`, no nonce. So a *forced* refresh that ran as a 
GTF task would recompute on the web worker on read-back instead of reading the 
result its task had cached, and could even serve stale data if the forced 
result had not been persisted. This diverged from the Redux path, which already 
threads the per-query task ids as forced-refresh nonces.
   
   Fix: widen the injected `handleAsyncChartData` refetch signature to 
`(queryForceNonces?: string[]) => Promise<QueryData[]>`, and on a forced 
read-back re-send `force: true` with each query stamped `queries[i].force_nonce 
= task_ids[i]` (the task UUID *is* the idempotency nonce). `async_mode` is 
intentionally omitted so the read-back resolves inline from the warm cache. 
Non-forced reads carry neither `force` nor a nonce.
   
   **2. Duplicate-tab id race (`useTabId`).**
   `useTabId` installed its `BroadcastChannel` message handler *after* 
broadcasting `REQUESTING_TAB_ID`, and the handler compared incoming denials 
against the render-captured `tabId` (which is `undefined` on the first render). 
A peer's immediate `TAB_ID_DENIED` for the just-claimed id could therefore be 
dropped, leaving two tabs sharing a tab id — which then collide on the 
backend's per-tab consumer key (`<principal>:<tab_id>`) used for async task 
fanout/cancel.
   
   Fix: install the listener *before* broadcasting; compare against a live 
mutable local id (`currentId`) instead of the render-captured state; and use 
`addEventListener` + an effect cleanup (`removeEventListener`) instead of the 
shared singleton `onmessage`.
   
   ### BEFORE/AFTER SCREENSHOTS OR ANIMATED GIF
   
   N/A (no visual change).
   
   ### TESTING INSTRUCTIONS
   
   - `npm run test -- 
packages/superset-ui-core/src/chart/components/StatefulChart.test.tsx 
src/hooks/useTabId.test.ts`
   - Manual: with `GLOBAL_ASYNC_QUERIES` + websocket enabled, force-refresh a 
Matrixify chart — the read-back reads cached results (single execution), and a 
not-yet-persisted forced result re-forces rather than serving stale data.
   - Manual: duplicate a browser tab (Ctrl/Cmd-click reload into a new tab of 
the same session) — the duplicate is reassigned a fresh tab id rather than 
silently sharing the incumbent's.
   
   ### ADDITIONAL INFORMATION
   - [ ] Has associated issue:
   - [ ] Required feature flags:
   - [x] 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
   
   ---
   Part of the GAQ → GTF migration epic (#43407).
   


-- 
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]

Reply via email to