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

   ### SUMMARY
   
   Follow-up to #43627 (merged), closing the one gap it explicitly deferred and 
tightening the reaper's schedule.
   
   **1. Cancel the orphaned warehouse query.** #43627 made async chart-data 
query tasks cancellable *while the worker is alive* (an `on_abort` handler runs 
`db_engine_spec.cancel_query` over a fresh connection). But when a **worker 
dies**, there's no live thread to run that handler, so the reaper only marked 
the `Task` `FAILURE` and revoked the Celery job — the abandoned warehouse query 
kept running until the warehouse's own statement/idle timeout. Now the reaper 
cancels it out-of-band.
   
   **2. Dedicated reaper beat job.** Reaping was folded into `prune_tasks`. 
Reaping wants a *short* cadence (detect a dead worker — and cancel its query — 
within ~a minute); retention pruning is a heavy, infrequent bulk DELETE. One 
shared cadence can't serve both, so reaping now runs on its own 
`reap_orphaned_tasks` beat schedule.
   
   #### How the orphan-cancel works
   
   The reaper runs in a different process from the dead worker, so the engine 
cancel-id must be on the `Task` row:
   
   - **Persist at capture** — when the capture sink obtains a cancel-id, 
`TaskContext.set_cancellation(database_id, cancel_id)` merges 
`{cancel_database_id, cancel_query_id}` into the property cache. It does 
**not** write: the task registers its abort handler immediately after, and that 
`is_abortable` write already flushes the whole cache — so the handle is 
persisted in an existing write, **no extra DB write** on the hot path. Only 
engines that expose a cancel-id before execution 
(Postgres/MySQL/Snowflake/Redshift, as in the live path) persist a handle.
   - **Reaper cancels** — `ReapOrphanedTasksCommand._reap` reads the handle, 
loads the `Database`, and reuses the existing `cancel_chart_query(database, 
cancel_id)` helper (fresh connection, id validation, `gtf.query.cancel` / 
`gtf.query.cancel_failed` metrics) **before** the revoke + CAS→`FAILURE`. 
Best-effort: no handle, a missing database, or a cancel failure never blocks 
the FAILURE transition. A dead worker holds no lock on the row, so this is 
race-free.
   
   No new helper, config key, or migration — `cancel_chart_query` and the 
reaper already exist; this reuses them. The live abort path is unchanged (it 
still uses the in-memory closure).
   
   #### Scheduling change
   
   - `reap_orphaned_tasks` is a new Celery beat task; `prune_tasks` reverts to 
retention-only. `CELERY_CONFIG.beat_schedule` gains a commented 
`reap_orphaned_tasks` template on a short interval (e.g. every minute), 
separate from the `prune_tasks` retention template. Docs/UPDATING updated.
   
   ### TESTING INSTRUCTIONS
   
   - Unit (`tests/unit_tests/tasks/`): `TaskContext.set_cancellation` merges 
the handle into the cache (persisted by the ensuing `is_abortable` write, 
existing keys preserved); the capture sink calls `set_cancellation` before 
`on_abort` (and neither without a cancel-id); `_reap` calls 
`cancel_chart_query` with the persisted `(database, cancel_id)` when present, 
skips it when absent or the database is gone, and reaps regardless; 
`reap_orphaned_tasks` delegates to the command.
   - Integration (`tests/integration_tests/tasks/commands/test_reap.py`): an 
orphan with a persisted handle → the reaper invokes `cancel_chart_query` with 
the loaded `Database` and still ends the row `FAILURE`.
   - Manual (Celery worker + `reap_orphaned_tasks` beat + 
`DISTRIBUTED_COORDINATION_CONFIG`, a cancellable engine like Postgres): run an 
async chart query, `kill -9` the worker mid-query → within 
`GTF_ORPHAN_TASK_TIMEOUT` the task is `FAILURE` and the backend query is gone 
from `pg_stat_activity`.
   
   ### ADDITIONAL INFORMATION
   
   - [ ] Has associated issue:
   - [x] Required feature flags: `GLOBAL_TASK_FRAMEWORK` (async chart data also 
needs `GLOBAL_ASYNC_QUERIES`)
   - [ ] Changes UI
   - [ ] Includes DB Migration (the `cancel_*` handle lives in the existing 
`properties` JSON blob — no schema change)
   - [x] 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]

Reply via email to