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]