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

   ### SUMMARY
   
   **Step 4 of the GAQ→GTF epic (#43407): the chart-data cutover.** Async 
chart-data
   requests now run entirely on the **Global Task Framework** instead of the 
bespoke
   Global Async Queries (GAQ) plumbing — one GTF task per `QueryObject`, a 
lightweight
   status poll, and a client re-request on completion. This subsumes the old
   "frontend re-request" and "remove query-context wrapper" steps into one 
cutover.
   
   Because the whole `gaq-to-gtf` branch merges to `master` as a unit, this 
takes the
   **breaking** simplifications now rather than carrying compatibility shims:
   
   **Backend**
   - **Fan-out:** `/chart/data` (async) schedules one **SHARED** GTF task per 
`QueryObject`,
     keyed by its `query_cache_key` (safe cross-user dedup — the key encodes
     RLS/impersonation). Contribution queries `depends_on` the totals query's 
task and read
     its cached result to normalize. Dedicated task type 
**`superset.query_object_v1`**.
     The 202 body is `{"task_ids": [...]}`.
   - **No coordinator task, no `qc-<hash>` wrapper:** the client aggregates the 
query tasks'
     own honest statuses itself. Removed the `/api/v1/chart/data/<cache_key>` 
replay
     endpoint, `QueryContextCacheLoader`, and `result_url`.
   - **New poll primitive `GET /api/v1/task/status_changes`:** returns
     `{statuses: {uuid: {status, progress}}, cursor}` for tasks the caller can 
see
     (`TaskFilter`-scoped), changed since an opaque server-issued cursor 
(`changed_on >=`,
     so no transition is missed; re-delivery is idempotent). No cursor = 
baseline
     (empty + current watermark; never dumps all tasks). Optional `task_type` 
filter.
   - **Embedded-guest visibility:** guests have no `ab_user` id, so they now 
subscribe to
     tasks by a stable, token-derived `guest_key` (HMAC over guest-token claims 
keyed with
     `SECRET_KEY`); `TaskFilter` honors it. Survives SHARED-scope dedup (two 
equivalent
     guests collapse to one task and both subscribe). Adds a nullable
     `task_subscribers.guest_key` column (reversible migration; `user_id` 
relaxed to
     nullable — a subscriber is exactly one of `user_id`/`guest_key`).
   - **GAQ rip-out:** deleted `AsyncQueryManager`, the `/api/v1/async_event/` 
REST API, the
     factory, and the legacy `load_chart_data_into_cache` Celery task. Removed 
the GAQ
     JWT/cookie/transport/stream config **and** the dedicated
     `GLOBAL_ASYNC_QUERIES_CACHE_BACKEND` — coordination now runs on
     `DISTRIBUTED_COORDINATION_CONFIG` exclusively. Kept the 
`GLOBAL_ASYNC_QUERIES` flag and
     `GLOBAL_ASYNC_QUERIES_POLLING_DELAY`.
   
   **Frontend**
   - Rewrote `asyncEvent.ts` off the GAQ firehose (poll + WebSocket + 
`result_url`) to a
     single shared cursor-poll of `status_changes` filtered to 
`superset.query_object_v1`.
     `waitForAsyncData(job, refetch, signal)` awaits the job's `task_ids` to 
all reach
     `SUCCESS`, then calls `refetch()` (re-issues the original request — served
     synchronously from the now-warm per-query DATA cache); any terminal 
non-success
     rejects; abort cancels the tasks via `/api/v1/task/<uuid>/cancel`.
   - Threaded the re-request through `chartAction.exploreJSON`, `FilterValue`,
     `FiltersConfigForm`, `DrillByModal`, `ChartVersionPreview`, and 
`StatefulChart`'s
     `handleAsyncChartData` hook.
   
   **Auth / transport notes**
   - Polling and cancel use the caller's normal Superset session 
(`@protect()`); embedded
     guests use their existing guest token. The GAQ JWT is no longer needed.
   - Real-time WebSocket push (previously via the GAQ firehose) is 
intentionally retired
     here; async chart-data is **polling-only** on the branch. A GTF-native 
WebSocket
     transport returns in a later epic step with its own channel-token service.
   
   ### BEFORE/AFTER SCREENSHOTS OR ANIMATED GIF
   
   N/A — no user-visible UI change (async chart loading behaves the same; the 
transport
   underneath changed).
   
   ### TESTING INSTRUCTIONS
   
   With `GLOBAL_ASYNC_QUERIES` enabled (which also enables 
`GLOBAL_TASK_FRAMEWORK`) and
   `DISTRIBUTED_COORDINATION_CONFIG` pointed at Redis/Valkey:
   - Load a dashboard with multi-query + contribution charts; confirm each 
chart resolves
     (tasks appear in the Task List as `superset.query_object_v1`, then the 
chart renders).
   - Confirm a second load short-circuits to a synchronous 200 (warm cache).
   - Press Stop mid-load; confirm the outstanding tasks are cancelled.
   - Load an embedded (guest-token) dashboard; confirm async charts resolve.
   
   Automated: `pytest tests/unit_tests/tasks tests/unit_tests/coordination 
tests/unit_tests/daos/test_tasks.py`
   (393 pass locally); frontend `npm run test -- asyncEvent chartActions 
StatefulChart FilterValue`.
   Migration up/down/up verified reversible on SQLite.
   
   ### ADDITIONAL INFORMATION
   
   - [ ] Has associated issue:
   - [x] Required feature flags: `GLOBAL_ASYNC_QUERIES` (auto-enables 
`GLOBAL_TASK_FRAMEWORK` in a later step)
   - [x] Changes UI
   - [x] Includes DB Migration (follow approval process in 
[SIP-59](https://github.com/apache/superset/issues/13351))
     - [x] Migration is atomic, supports rollback & is backwards-compatible
     - [x] Confirm DB migration upgrade and downgrade tested
     - [ ] Runtime estimates and downtime expectations provided
   - [x] Introduces new feature or API (`/api/v1/task/status_changes`; 
per-`QueryObject` async tasks)
   - [x] Removes existing feature or API (`/api/v1/async_event/`, 
`AsyncQueryManager`, `qc-<hash>` replay, `GLOBAL_ASYNC_QUERIES_CACHE_BACKEND` + 
GAQ JWT/transport config)
   
   ---
   
   **Follow-ups (not this PR):** rip the now-dead 
`cache_query_context`/`qc-<hash>` `cache_key()`
   write path from `QueryContextProcessor` (harmless dead write today; touches 
the
   `/chart/data` response shape, so done separately); `async_mode` per-request 
opt-in +
   `GLOBAL_ASYNC_QUERIES` → `GLOBAL_TASK_FRAMEWORK` auto-enable (next step); 
GTF-native
   WebSocket transport.
   
   Targets the `gaq-to-gtf` feature branch (part of #43407), not `master`.
   


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