Skip to content

Cancel the Redshift statement when a user kills the deferred task - #69676

Merged
potiuk merged 1 commit into
apache:mainfrom
steveahnahn:redshift-cancel-statement-on-user-kill-deferred
Aug 1, 2026
Merged

Cancel the Redshift statement when a user kills the deferred task#69676
potiuk merged 1 commit into
apache:mainfrom
steveahnahn:redshift-cancel-statement-on-user-kill-deferred

Conversation

@steveahnahn

@steveahnahn steveahnahn commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Problem

  • RedshiftDataOperator.on_kill cancels the running statement, but after defer() the worker is gone and it can never run.
  • RedshiftDataTrigger had no on_kill (base default is a no op), so killing a deferred task orphans the statement: RPU hours keep billing on Serverless, a WLM slot stays held on a provisioned cluster.
  • Sibling triggers already cancel on user kill: EMR here, BigQuery/Dataproc/Dataflow in the Google provider.

Change

  • Add on_kill to RedshiftDataTrigger: cancels via the hook's async connection (cancel_statement).
  • CancelStatement returns {"Status": bool}; a declined cancel (statement already finished) logs a warning instead of claiming success.
  • cancel_on_kill flag (default True) on operator and trigger; operator threads it into the trigger at the defer site.
  • Best effort: cancel failures are logged and swallowed. Fires only on user kill, never on triggerer restart, redistribution, or timeout.

Live verification

  1. Deferrable operator submitted a statement (STARTED); task deferred, trigger polling via the real aiobotocore client.

deferred task, trigger polling the statement

  1. Marked the task failed from the UI.

marking the deferred task failed

  1. Triggerer log, no exception escaping:
Trigger cancelled by user action, invoking on_kill
Cancelling Redshift statement 93e26017-b365-4c9f-9c58-9d387af5e6ea.
Redshift statement 93e26017-b365-4c9f-9c58-9d387af5e6ea cancelled.
  1. DescribeStatement returned Status: ABORTED. Without the change the statement stays STARTED (base on_kill is a no op).

Tests

  • Trigger: cancel on kill (parametrized over Status True/False with the real response shape), disabled/missing id no ops, error swallowing, serialization of the flag.
  • Operator: cancel_on_kill=False guard, flag threaded into the trigger on defer (both True and False).
  • Every new assertion fails without the source change.

Was generative AI tooling used to co-author this PR?
  • Yes, Claude Code (Fable 5)

Generated-by: Claude Code (Fable 5) following the guidelines

@boring-cyborg boring-cyborg Bot added area:providers provider:amazon AWS/Amazon - related issues labels Jul 9, 2026
A deferred RedshiftDataOperator parks its query in the triggerer, so the
operator's own on_kill no longer runs once the task is deferred. When a user
marks that task failed, clears it, or marks it success, the trigger had no
on_kill hook, so the Redshift statement kept running against the cluster or
workgroup even though the operator already cancels the statement on kill in
the non-deferred path. On Redshift Serverless a runaway statement keeps
billing RPU-hours, and on a provisioned cluster it holds a WLM slot, until it
finishes on its own.

This adds on_kill to RedshiftDataTrigger to cancel the running statement when
the user acts on the deferred task, matching the behaviour already shipped for
the EMR, Dataproc, BigQuery, and Dataflow triggers. A cancel_on_kill flag on
both the operator and the trigger lets users opt out.
@steveahnahn
steveahnahn force-pushed the redshift-cancel-statement-on-user-kill-deferred branch from 02ddfa7 to af96bfc Compare July 10, 2026 19:54
@steveahnahn
steveahnahn marked this pull request as ready for review July 10, 2026 22:59
@steveahnahn
steveahnahn requested a review from o-nikolas as a code owner July 10, 2026 22:59
@potiuk potiuk added the ready for maintainer review Set after triaging when all criteria pass. label Jul 11, 2026

@potiuk potiuk left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch on a gap with a direct running cost — after defer() the worker is gone, so the operator's on_kill could never fire, and an orphaned statement keeps billing RPU hours on Serverless or holds a WLM slot on a provisioned cluster.

The part I care most about is where the cancellation lives, and it is in the right place. BaseTrigger's own docstring warns that putting external job cancellation in cleanup() would cancel in-flight work on every triggerer restart or rolling deploy; this uses on_kill(), and the triggerer only invokes that on an explicit user action — the timeout path raises without calling it. So a deploy will not take out live queries. It is also bounded by _ON_CANCEL_TIMEOUT, so a slow cancel cannot wedge the triggerer.

Adding cancel_on_kill to serialize() matters more than it looks: without it the flag would be silently dropped crossing into the triggerer, and the opt-out would appear to work while doing nothing.

Handling CancelStatement returning Status=False is a nice detail — reporting "declined, may have already finished" rather than claiming a successful cancel is the difference between a log you can trust and one you cannot. Swallowing cancel errors with log.exception is right too; a failed cancel must not block the kill.

Worth being explicit in the release notes that killing a deferred task now cancels the statement where it previously orphaned it. That is the intended fix, and cancel_on_kill=False is the escape hatch, but it does change what a kill does for anyone who had built expectations around the old behaviour.


Drafted-by: Claude Code (Opus 5); reviewed by @potiuk before posting

@potiuk
potiuk merged commit d9b7eb0 into apache:main Aug 1, 2026
160 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:providers provider:amazon AWS/Amazon - related issues ready for maintainer review Set after triaging when all criteria pass.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants