Skip to content

Add deferrable mode to QuickSight operator and sensor - #70218

Merged
o-nikolas merged 4 commits into
apache:mainfrom
ozemin:quicksight-deferrable
Sep 10, 2026
Merged

o-nikolas merged 4 commits into
apache:mainfrom
ozemin:quicksight-deferrable

Conversation

@ozemin

@ozemin ozemin commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Adds deferrable=True support to QuickSightCreateIngestionOperator and QuickSightSensor, following the same waiter-based pattern as the rest of the Amazon provider. QuickSight has no official boto3 waiters (boto/boto3#2769), so this adds a custom ingestion_complete waiter and a QuickSightIngestionCompletedTrigger, and replaces the hook's hand-written polling loop, which held a worker slot with time.sleep and had no upper bound.

One thing without a direct precedent: DescribeIngestion requires AwsAccountId, so it is resolved on the worker before deferring and passed to the trigger — the triggerer never makes a sync STS call.

Behaviour changes: the synchronous wait is now bounded by waiter_max_attempts (default 60 attempts × 30s) instead of waiting forever; noted in the provider changelog. QuickSightHook.wait_for_state and the operator's check_interval are deprecated (still working) in favour of wait_for_ingestion / waiter_delay. Failures raise QuickSightIngestionFailedError, an AirflowException subclass.


Was generative AI tooling used to co-author this PR?
  • Yes — Claude Code

@o-nikolas o-nikolas left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Looks like there are conflicts and build failures that need looking at. Also, I'm not sure of the breaking change (the new 30min timeout). I think large ingestions will easily pass that and fail dags for folks using this operator. We could make the default much higher, or go through a deprecation process where we log that the user should switch to setting a high default before we remove it. Or wait until a major release for the amazon provider package.

Curious what @vincbeck and @ferruzzi think

Comment thread providers/amazon/docs/changelog.rst Resolved
@ozemin

ozemin commented Jul 27, 2026

Copy link
Copy Markdown
Contributor Author

We could make the default much higher

Raised the default wait to 36 hours: 4320 attempts at the 30s delay, or 2160 at the sensor's 60s poke interval. That's how long AWS itself waits on a SPICE ingestion in the CloudFormation wait policy, where 36 hours is both the default and the maximum:

https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-quicksight-dataset-ingestionwaitpolicy.html

@ozemin
ozemin force-pushed the quicksight-deferrable branch from ca7307e to 5e254c3 Compare July 27, 2026 19:24
@ozemin
ozemin requested review from o-nikolas and vincbeck August 5, 2026 08:15
@vincbeck

Copy link
Copy Markdown
Contributor

Static checks are failing

ozemin added 4 commits August 22, 2026 00:38
The QuickSight create-ingestion wait path used a hand-written polling
loop that held a worker slot with time.sleep and had no upper bound, so
a stuck ingestion could block a worker indefinitely. Moving the wait to
a custom boto waiter lets both the operator and the sensor defer to the
triggerer with deferrable=True, matching the deferrable pattern used
across the Amazon provider, and bounds the synchronous wait as well.
AWS waits up to 36 hours for a SPICE ingestion in its own CloudFormation
wait policy, where 36 hours is both the default and the maximum.
Refreshes that run for several hours are common, so a shorter cap fails
Dags that previously waited without a limit.

https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-quicksight-dataset-ingestionwaitpolicy.html
check_interval is a template field, so a constructor that branches on it
reads the un-rendered Jinja expression rather than the value the task will
actually use. Emitting the warning where the deprecated value is resolved
keeps it tied to the real input.
@ozemin
ozemin force-pushed the quicksight-deferrable branch from 5e254c3 to 71ab048 Compare August 21, 2026 21:47
@o-nikolas
o-nikolas merged commit 76ffb46 into apache:main Sep 10, 2026
89 checks passed
@boring-cyborg

boring-cyborg Bot commented Sep 10, 2026

Copy link
Copy Markdown

Awesome work, congrats on your first merged pull request! You are invited to check our Issue Tracker for additional contributions.

imrichardwu pushed a commit to imrichardwu/airflow that referenced this pull request Sep 11, 2026
The QuickSight create-ingestion wait path used a hand-written polling
loop that held a worker slot with time.sleep and had no upper bound, so
a stuck ingestion could block a worker indefinitely. Moving the wait to
a custom boto waiter lets both the operator and the sensor defer to the
triggerer with deferrable=True, matching the deferrable pattern used
across the Amazon provider, and bounds the synchronous wait as well.

AWS waits up to 36 hours for a SPICE ingestion in its own CloudFormation
wait policy, where 36 hours is both the default and the maximum.
Refreshes that run for several hours are common, so a shorter cap fails
Dags that previously waited without a limit.
xvega pushed a commit to xvega/airflow that referenced this pull request Sep 13, 2026
The QuickSight create-ingestion wait path used a hand-written polling
loop that held a worker slot with time.sleep and had no upper bound, so
a stuck ingestion could block a worker indefinitely. Moving the wait to
a custom boto waiter lets both the operator and the sensor defer to the
triggerer with deferrable=True, matching the deferrable pattern used
across the Amazon provider, and bounds the synchronous wait as well.

AWS waits up to 36 hours for a SPICE ingestion in its own CloudFormation
wait policy, where 36 hours is both the default and the maximum.
Refreshes that run for several hours are common, so a shorter cap fails
Dags that previously waited without a limit.
dlactin pushed a commit to dlactin/airflow that referenced this pull request Sep 14, 2026
The QuickSight create-ingestion wait path used a hand-written polling
loop that held a worker slot with time.sleep and had no upper bound, so
a stuck ingestion could block a worker indefinitely. Moving the wait to
a custom boto waiter lets both the operator and the sensor defer to the
triggerer with deferrable=True, matching the deferrable pattern used
across the Amazon provider, and bounds the synchronous wait as well.

AWS waits up to 36 hours for a SPICE ingestion in its own CloudFormation
wait policy, where 36 hours is both the default and the maximum.
Refreshes that run for several hours are common, so a shorter cap fails
Dags that previously waited without a limit.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants