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

   ### SUMMARY
   
   **Step 6 of the GAQ→GTF epic (#43407): realtime websocket transport — 
backend foundation.** Step 4 removed the GAQ firehose + `async-token` JWT that 
the old `superset-websocket` server relied on (async chart-data went 
polling-only). This PR lays the **backend foundation** for a generalized, 
GTF-native realtime push transport. The Node server rewrite and the frontend 
socket client follow in subsequent slices (see *Remaining* below).
   
   The transport has **two tiers**, each with the authorization that fits it:
   
   - **Public per-entity-type pub/sub** (lossy, list-view activity). GTF 
publishes an **opaque** change nudge — `{entity_type, id}`, no status or 
payload — to a per-type channel (`entity-changes:task`, later `:dashboard`, 
`:chart`, `:dataset`, …). A list view subscribes only to its type and 
re-fetches the actual (authz-scoped) data through the authorized REST API on a 
nudge. The contract is general across all entity types; id existence is 
intentionally public, so this channel never carries authz-sensitive data.
   - **Per-principal channel** (dashboard chart-data path). A connection is 
authenticated by a JWT cookie and bound to a deterministic per-principal 
channel (`user:<id>` / `guest:<hmac>`); the server delivers a channel's events 
only to that principal's sockets — the same isolation master's async-events 
transport had, so this path can carry sensitive completion detail. (The publish 
side + delivery are wired in the Node/frontend slices.)
   
   **What's in this PR (backend foundation)**
   
   - `TaskManager.publish_entity_change(task_uuid)` — best-effort pub/sub of 
the opaque nudge to `entity-changes:task` on task completion (emitted alongside 
the existing guaranteed completion signal; strictly best-effort, never disrupts 
it — the interval poll remains the backstop).
   - `superset/websocket/channel.py` — a feature-agnostic channel-token service 
(replacing the GAQ `async-token` handshake removed in step 4): 
`get_channel_id()` (per-principal, reusing the guest identity from 
`superset.tasks.guest`), `mint_channel_token()`, and 
`register_ws_channel_cookie()` (an `after_request` `httponly` JWT cookie the 
websocket server verifies). Deterministic per-principal channels (vs the legacy 
per-session-random) let the task layer publish a user's events to their channel.
   - New `WEBSOCKET_*` config (`WEBSOCKET_ENABLED`, `WEBSOCKET_URL`, 
`WEBSOCKET_JWT_SECRET`, 
`WEBSOCKET_JWT_COOKIE_NAME`/`_SECURE`/`_SAMESITE`/`_DOMAIN`/`_EXPIRATION_SECONDS`),
 a gated `configure_websocket()` in initialization, and 
`WEBSOCKET_ENABLED`/`WEBSOCKET_URL` exposed to the frontend bootstrap.
   
   ### BEFORE/AFTER SCREENSHOTS OR ANIMATED GIF
   
   N/A — backend only; no user-visible change until the Node/frontend slices 
land.
   
   ### TESTING INSTRUCTIONS
   
   Automated: `pytest tests/unit_tests/tasks/test_manager.py 
tests/unit_tests/websocket/`. With `DISTRIBUTED_COORDINATION_CONFIG` set, 
completing a GTF task publishes `{entity_type: "task", id}` on 
`entity-changes:task` (best-effort). With `WEBSOCKET_ENABLED=True` + a 
`WEBSOCKET_JWT_SECRET`, authenticated responses carry the `superset-ws-token` 
cookie whose `channel` claim is `user:<id>` (or `guest:<hmac>`).
   
   ### ADDITIONAL INFORMATION
   
   - [ ] Has associated issue:
   - [ ] Required feature flags:
   - [ ] Changes UI
   - [ ] Includes DB Migration
   - [x] Introduces new feature or API (realtime entity-change pub/sub; 
websocket channel-token service + `WEBSOCKET_*` config)
   - [ ] Removes existing feature or API
   
   ---
   
   **Remaining step-6 slices (this PR or immediate follow-ups):** per-principal 
chart-data publish (task completion → submitter's channel); rewrite 
`superset-websocket/src/index.ts` (subscribe the public `entity-changes:*` 
broadcast + route per-principal channel events by the JWT `channel` claim; drop 
the `async-events-full`/`result_url` firehose model); frontend socket client in 
`asyncEvent.ts` (accelerate chart-data completion + trigger list re-fetches; 
interval poll stays the fallback); config/docker/docs. Shipping the websocket 
server on the official image is **step 8** (#43407 tracker).
   
   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