fix(explore): stop button cancels running chart queries in the backend
User description
SUMMARY
This PR fixes Issue #35347, where the Stop button in Chart and Dashboard views did not actually stop running queries on Trino and other databases.
Previously:
- The stop button in the Explore/Chart view was not wired to the backend cancellation logic.
- Chart queries were effectively stateless from the perspective of cancellation and did not carry query_id / client tracking information used by the backend to kill queries.
- As a result, clicking Stop, closing the tab, refreshing the page, or navigating away would still leave the query running on the database, consuming unnecessary compute resources.
This PR:
- Adds client and query tracking for chart queries so they carry the necessary identifiers for cancellation.
- Wires the chart stop button to a new backend API endpoint that uses the same query-killing logic already used by SQL Lab.
- Ensures that when a user clicks Stop in Chart view, a cancellation request is sent to the backend, which then kills the corresponding running query on the database.
Key changes include:
Frontend:
superset-frontend/src/components/Chart/chartAction.jssuperset-frontend/src/components/Chart/chartReducer.tssuperset-frontend/src/explore/components/ExploreViewContainer/index.jsxsuperset-frontend/src/explore/exploreUtils/index.jssuperset-frontend/src/explore/types.ts
These changes add client/query tracking to chart queries and connect the Stop button to the new cancellation API.
Backend:
superset/charts/schemas.pysuperset/common/query_context.pysuperset/common/query_context_factory.pysuperset/common/query_context_processor.pysuperset/models/core.pysuperset/models/helpers.py
These changes ensure that chart queries are created with client/query identifiers and that the backend can locate and cancel the corresponding running query.
Behaviorally, there are no breaking changes: the Stop button now behaves as expected by users (similar to SQL Lab), and no existing functionality is regressed.
BEFORE/AFTER SCREENSHOTS OR ANIMATED GIF
No visual UI changes. The Stop button remains the same visually; only its behavior is corrected (it now kills the backend query).
Behavioral demonstration:
- Before: Clicking Stop in Chart view would stop the frontend loading indicator, but the query continued running in the database (e.g., Trino), wasting resources.
- After: Clicking Stop in Chart view sends a cancellation request to the backend, which kills the query in the database. The query transitions to a cancelled/killed state (e.g.,
USER ERROR: ADMINISTRATIVELY KILLEDin Trino).
TESTING INSTRUCTIONS
- Set up Superset with Trino (or another supported DB where you can see running queries).
- Start Superset and log in.
- Go to Explore / Create Chart and configure a chart that triggers a long-running query (e.g., a heavy query against Trino).
- Open the Trino UI (or the database's query monitoring UI) to observe running queries.
- In Chart view, run the chart and confirm the query appears as running in Trino.
- Click the Stop button in Chart view.
- Verify in the Trino UI that:
- The query is cancelled, and
- It transitions to an error such as
USER ERROR: ADMINISTRATIVELY KILLED(or the equivalent cancellation message for your database).
- Repeat the above steps from a Dashboard that contains a chart to confirm that stopping from the Dashboard view also cancels the underlying query.
Additionally:
- Run the existing test suite to ensure no regressions:
pytest(backend)npm test/pnpm test(frontend), as appropriate for the repo setup.
- Confirm that SQL Lab query cancellation behavior remains unchanged and still works as expected (regression check).
ADDITIONAL INFORMATION
- [x] Has associated issue: Fixes #35347
- [ ] Required feature flags:
- [ ] Changes UI
- [ ] Includes DB Migration (follow approval process in SIP-59)
- [ ] Migration is atomic, supports rollback & is backwards-compatible
- [ ] Confirm DB migration upgrade and downgrade tested
- [ ] Runtime estimates and downtime expectations provided
- [x] Introduces new feature or API
- [ ] Removes existing feature or API
Additional notes:
- No new external dependencies are introduced.
- No performance concerns identified; cancelling queries should reduce unnecessary resource usage.
- No DB migrations are required.
- The change reuses the existing SQL Lab query cancellation mechanism, ensuring consistent behavior across SQL Lab and Explore/Chart views.
Contributors:
CodeAnt-AI Description
Make the Explore chart Stop button cancel running database queries
What Changed
- Clicking Stop in Explore now cancels the underlying database query, not just the in-flight HTTP request
- Each chart query now includes a client-generated id so the backend can track and stop that specific query
- Query cancellation is more robust across databases, reducing cases where a stopped chart leaves work running in the database
- If the backend fails to stop a query, the UI shows a clear toast error instead of failing silently
Impact
✅ Chart queries can be reliably cancelled from Explore
✅ Fewer abandoned long-running chart queries after clicking Stop or navigating away
✅ Lower database load from cancelled or abandoned chart runs
💡 Usage Guide
Checking Your Pull Request
Every time you make a pull request, our system automatically looks through it. We check for security issues, mistakes in how you're setting up your infrastructure, and common code problems. We do this to make sure your changes are solid and won't cause any trouble later.
Talking to CodeAnt AI
Got a question or need a hand with something in your pull request? You can easily get in touch with CodeAnt AI right here. Just type the following in a comment on your pull request, and replace "Your question here" with whatever you want to ask:
@codeant-ai ask: Your question here
This lets you have a chat with CodeAnt AI about your pull request, making it easier to understand and improve your code.
Example
@codeant-ai ask: Can you suggest a safer alternative to storing this secret?
Preserve Org Learnings with CodeAnt
You can record team preferences so CodeAnt AI applies them in future reviews. Reply directly to the specific CodeAnt AI suggestion (in the same thread) and replace "Your feedback here" with your input:
@codeant-ai: Your feedback here
This helps CodeAnt AI learn and adapt to your team's coding style and standards.
Example
@codeant-ai: Do not flag unused imports.
Retrigger review
Ask CodeAnt AI to review the PR again, by typing:
@codeant-ai: review
Check Your Repository Health
To analyze the health of your code repository, visit our dashboard at https://app.codeant.ai. This tool helps you identify potential issues and areas for improvement in your codebase, ensuring your repository maintains high standards of code health.
/review
/review
Code Review Agent Run #1b36c1
Actionable Suggestions - 0
Additional Suggestions - 7
-
superset/models/core.py - 1
-
Use logging instead of print · Line 825-831The added debug output uses print(), which sends to stdout and can interfere with production logging systems. Replace with logger.debug() using the existing logger instance for consistent debug handling.
Code suggestion
@@ -824,8 +824,1 @@ - try: - print( - f"[Database.get_df] called for database_id={getattr(self, 'id', None)} " - f"query_id={getattr(query, 'id', None) if query is not None else None} " - f"client_id={getattr(query, 'client_id', None) if query is not None else None}" - ) - except Exception: - logger.debug("Could not print Database.get_df debug info", exc_info=True) + logger.debug( + f"[Database.get_df] called for database_id={getattr(self, 'id', None)} " + f"query_id={getattr(query, 'id', None) if query is not None else None} " + f"client_id={getattr(query, 'client_id', None) if query is not None else None}" + )
-
-
superset-frontend/src/explore/components/ExploreViewContainer/index.jsx - 1
-
Inconsistent Error Handling · Line 414-416The error handling here uses console.error, but SqlLab's equivalent code uses addDangerToast for user-visible notifications. Consider updating to props.addDangerToast('Failed to stop query.') to provide consistent UX across the app.
Code suggestion
@@ -414,3 +414,3 @@ - }).catch(error => { - console.error('Error stopping query on backend:', error); - }); + }).catch(error => { + props.addDangerToast('Failed to stop query.'); + });
-
-
superset-frontend/src/explore/exploreUtils/index.js - 1
-
Remove debug console.log · Line 243-243The console.log on line 243 appears to be a debug statement left in production code. According to the contributing guidelines, debug statements like this should be removed to keep the codebase clean.
-
-
superset/sql_lab.py - 2
-
Logging Level Too Low · Line 687-690The logging level for prepare_cancel_query failures is set to debug, which may not be enabled in production environments. Consider upgrading to warning level for better observability of potential database preparation issues.
Code suggestion
@@ -690,1 +690,1 @@ - logger.debug("prepare_cancel_query failed", exc_info=True) + logger.warning("prepare_cancel_query failed", exc_info=True) -
Inconsistent Error Logging · Line 712-718cancel_query exceptions are caught but not logged, unlike prepare_cancel_query. This inconsistency makes debugging cancel failures harder. Consider adding warning-level logging here too.
-
-
superset-frontend/src/components/Chart/chartAction.js - 2
-
Lint violation: console statement · Line 386-386This console.log statement violates the project's lint rules against console statements in production code. It should be removed to maintain code quality standards.
Code suggestion
@@ -384,6 +384,2 @@ - export function handleChartDataResponse(response, json, useLegacyApi) { - - console.log('handleChartDataResponse', response, json, useLegacyApi); - // todo: hopefully handle responses of chart view - - if (isFeatureEnabled(FeatureFlag.GlobalAsyncQueries)) { + export function handleChartDataResponse(response, json, useLegacyApi) { + // todo: hopefully handle responses of chart view + if (isFeatureEnabled(FeatureFlag.GlobalAsyncQueries)) { -
Lint violation: console statement · Line 438-438This console.log statement violates the project's lint rules against console statements in production code. It should be removed to maintain code quality standards.
Code suggestion
@@ -437,4 +437,3 @@ - const clientId = nanoid(11); - console.log('Generated client_id for chart query:', clientId); - - dispatch(chartUpdateStarted(controller, formData, key, clientId)); + const clientId = nanoid(11); + + dispatch(chartUpdateStarted(controller, formData, key, clientId));
-
Review Details
-
Files reviewed - 14 · Commit Range:
7506007..ea0d1ff- superset-frontend/src/components/Chart/chartAction.js
- superset-frontend/src/components/Chart/chartReducer.ts
- superset-frontend/src/explore/components/ExploreViewContainer/index.jsx
- superset-frontend/src/explore/exploreUtils/index.js
- superset-frontend/src/explore/types.ts
- superset/charts/schemas.py
- superset/common/query_context.py
- superset/common/query_context_factory.py
- superset/common/query_context_processor.py
- superset/connectors/sqla/models.py
- superset/daos/query.py
- superset/models/core.py
- superset/models/helpers.py
- superset/sql_lab.py
-
Files skipped - 0
-
Tools
- Eslint (Linter) - ✔︎ Successful
- Whispers (Secret Scanner) - ✔︎ Successful
- Detect-secrets (Secret Scanner) - ✔︎ Successful
- MyPy (Static Code Analysis) - ✔︎ Successful
- Astral Ruff (Static Code Analysis) - ✔︎ Successful
Bito Usage Guide
Commands
Type the following command in the pull request comment and save the comment.
-
/review- Manually triggers a full AI review. -
/pause- Pauses automatic reviews on this pull request. -
/resume- Resumes automatic reviews. -
/resolve- Marks all Bito-posted review comments as resolved. -
/abort- Cancels all in-progress reviews.
Refer to the documentation for additional commands.
Configuration
This repository uses Default Agent You can customize the agent settings here or contact your Bito workspace admin at [email protected].
Documentation & Help
/review
/review
Code Review Agent Run #bbca53
Actionable Suggestions - 0
Review Details
-
Files reviewed - 14 · Commit Range:
7506007..37d2e5e- superset-frontend/src/components/Chart/chartAction.js
- superset-frontend/src/components/Chart/chartReducer.ts
- superset-frontend/src/explore/components/ExploreViewContainer/index.jsx
- superset-frontend/src/explore/exploreUtils/index.js
- superset-frontend/src/explore/types.ts
- superset/charts/schemas.py
- superset/common/query_context.py
- superset/common/query_context_factory.py
- superset/common/query_context_processor.py
- superset/connectors/sqla/models.py
- superset/daos/query.py
- superset/models/core.py
- superset/models/helpers.py
- superset/sql_lab.py
-
Files skipped - 0
-
Tools
- Eslint (Linter) - ✔︎ Successful
- Whispers (Secret Scanner) - ✔︎ Successful
- Detect-secrets (Secret Scanner) - ✔︎ Successful
- MyPy (Static Code Analysis) - ✔︎ Successful
- Astral Ruff (Static Code Analysis) - ✔︎ Successful
Bito Usage Guide
Commands
Type the following command in the pull request comment and save the comment.
-
/review- Manually triggers a full AI review. -
/pause- Pauses automatic reviews on this pull request. -
/resume- Resumes automatic reviews. -
/resolve- Marks all Bito-posted review comments as resolved. -
/abort- Cancels all in-progress reviews.
Refer to the documentation for additional commands.
Configuration
This repository uses Default Agent You can customize the agent settings here or contact your Bito workspace admin at [email protected].
Documentation & Help
/review
Code Review Agent Run #27ee1d
Actionable Suggestions - 1
-
superset/common/query_context_processor.py - 1
- Blind exception catch without specific type · Line 126-164
Additional Suggestions - 1
-
superset-frontend/src/components/Chart/chartAction.js - 1
-
Parameter naming mismatch · Line 49-56The chartUpdateStarted function parameter is named latestQueryId but receives clientId (a client-generated tracking ID), which could confuse developers expecting a query ID. It looks like this might be intentional for tracking, but renaming to clientId would clarify the purpose and avoid potential misuse.
-
Review Details
-
Files reviewed - 14 · Commit Range:
7506007..4779744- superset-frontend/src/components/Chart/chartAction.js
- superset-frontend/src/components/Chart/chartReducer.ts
- superset-frontend/src/explore/components/ExploreViewContainer/index.jsx
- superset-frontend/src/explore/exploreUtils/index.js
- superset-frontend/src/explore/types.ts
- superset/charts/schemas.py
- superset/common/query_context.py
- superset/common/query_context_factory.py
- superset/common/query_context_processor.py
- superset/connectors/sqla/models.py
- superset/daos/query.py
- superset/models/core.py
- superset/models/helpers.py
- superset/sql_lab.py
-
Files skipped - 0
-
Tools
- Eslint (Linter) - ✔︎ Successful
- Whispers (Secret Scanner) - ✔︎ Successful
- Detect-secrets (Secret Scanner) - ✔︎ Successful
- MyPy (Static Code Analysis) - ✔︎ Successful
- Astral Ruff (Static Code Analysis) - ✔︎ Successful
Bito Usage Guide
Commands
Type the following command in the pull request comment and save the comment.
-
/review- Manually triggers a full AI review. -
/pause- Pauses automatic reviews on this pull request. -
/resume- Resumes automatic reviews. -
/resolve- Marks all Bito-posted review comments as resolved. -
/abort- Cancels all in-progress reviews.
Refer to the documentation for additional commands.
Configuration
This repository uses Default Agent You can customize the agent settings here or contact your Bito workspace admin at [email protected].
Documentation & Help
Looks like CI isn't happy at the moment. You'll at least need to run pre-commit, which might clear up some of the other failures too.
Superset uses Git pre-commit hooks courtesy of pre-commit. To install run the following:
pip3 install -r requirements/development.txt
pre-commit install
A series of checks will now run when you make a git commit.
Alternatively it is possible to run pre-commit by running pre-commit manually:
pre-commit run --all-files
CodeAnt AI is reviewing your PR.
Nitpicks 🔍
| 🔒 No security issues identified |
⚡ Recommended areas for review
|
CodeAnt AI finished reviewing your PR.
CodeAnt AI is running Incremental review