ExternalTaskSensor for cross-DAG dependencies in Apache Airflow - Time & Space Complexity
When using ExternalTaskSensor in Airflow, we want to know how waiting for another DAG's task affects execution time.
We ask: How does the sensor's checking grow as the number of dependencies or wait time increases?
Analyze the time complexity of this ExternalTaskSensor usage.
from airflow.sensors.external_task import ExternalTaskSensor
sensor = ExternalTaskSensor(
task_id='wait_for_task',
external_dag_id='other_dag',
external_task_id='task_to_wait_for',
poke_interval=60,
timeout=3600
)
This sensor waits for a task in another DAG to complete by checking every 60 seconds, timing out after 1 hour.
The sensor repeatedly checks if the external task is done.
- Primary operation: Periodic database query to check task status.
- How many times: Number of checks = timeout / poke_interval (e.g., 3600/60 = 60 times).
The number of checks grows linearly with the timeout length and inversely with poke interval.
| Input Size (timeout in seconds) | Approx. Checks |
|---|---|
| 600 (10 min) | 10 (if poke_interval=60s) |
| 3600 (1 hour) | 60 |
| 7200 (2 hours) | 120 |
Pattern observation: More waiting time means more checks, growing in a straight line.
Time Complexity: O(n)
This means the sensor's work grows directly with the number of checks it performs while waiting.
[X] Wrong: "The sensor checks only once, so time doesn't grow with timeout."
[OK] Correct: The sensor keeps checking repeatedly until the task finishes or timeout, so more wait means more checks.
Understanding how sensors wait and check helps you design efficient workflows and avoid unnecessary delays in real projects.
"What if we reduce the poke_interval to 10 seconds? How would the time complexity change?"
Practice
ExternalTaskSensor in Airflow?Solution
Step 1: Understand the role of ExternalTaskSensor
The ExternalTaskSensor is designed to pause a task until a specified task in a different DAG finishes successfully.Step 2: Compare with other options
Triggering DAGs, scheduling, and monitoring resources are handled by other components, not ExternalTaskSensor.Final Answer:
To wait for a task in another DAG to complete before proceeding -> Option AQuick Check:
ExternalTaskSensor waits for cross-DAG task completion [OK]
- Confusing ExternalTaskSensor with DAG trigger
- Thinking it schedules DAGs
- Assuming it monitors system resources
ExternalTaskSensor to wait for task 'task_a' in DAG 'dag_1'?Solution
Step 1: Identify correct parameter names
The ExternalTaskSensor requiresexternal_dag_idandexternal_task_idto specify the DAG and task it waits for.Step 2: Match parameters with options
Only ExternalTaskSensor(task_id='wait_task', external_dag_id='dag_1', external_task_id='task_a') uses the correct parameter names and syntax.Final Answer:
ExternalTaskSensor(task_id='wait_task', external_dag_id='dag_1', external_task_id='task_a') -> Option DQuick Check:
Use external_dag_id and external_task_id parameters [OK]
- Using wrong parameter names like dag_id or external_dag
- Confusing task_id with external_task_id
- Omitting required parameters
wait_for_task = ExternalTaskSensor(
task_id='wait_for_task_a',
external_dag_id='dag_1',
external_task_id='task_a',
mode='reschedule',
poke_interval=30
)
wait_for_task.execute(context={})What happens if
task_a in dag_1 has not completed yet?Solution
Step 1: Understand mode='reschedule'
In 'reschedule' mode, the sensor frees the worker slot between pokes, retrying after the poke_interval.Step 2: Analyze behavior when task not complete
The sensor will keep checking every 30 seconds without blocking a worker slot until the external task finishes.Final Answer:
The sensor waits and retries every 30 seconds without blocking a worker slot -> Option AQuick Check:
mode='reschedule' frees worker slot during wait [OK]
- Confusing 'reschedule' with 'poke' mode
- Assuming immediate failure if task incomplete
- Thinking sensor completes without waiting
wait_task = ExternalTaskSensor(
task_id='wait_task',
external_dag_id='dag_1',
external_task_id='task_a',
timeout=300
)
But the sensor never finishes even after
task_a completes. What is the likely cause?Solution
Step 1: Understand execution_date matching
ExternalTaskSensor waits for the external task with the same execution_date by default.Step 2: Identify mismatch issue
If the sensor's execution_date differs from the external task's, it will wait forever even if the external task completed.Final Answer:
The sensor's execution_date does not match the external task's execution date -> Option BQuick Check:
Execution dates must match for ExternalTaskSensor to succeed [OK]
- Assuming timeout controls waiting for task completion
- Confusing task_id with external_task_id
- Thinking poke_interval absence causes hang
task_b in dag_2 waits for task_a in dag_1 to succeed, but only for the same execution date. Which configuration ensures this behavior and avoids deadlocks?Solution
Step 1: Understand default execution_date behavior
By default, ExternalTaskSensor waits for the external task with the same execution_date, ensuring correct cross-DAG sync.Step 2: Avoid execution_date shifts
Using execution_date_fn to shift dates can cause deadlocks or missed dependencies.Step 3: Consider mode
mode='poke' works but does not affect execution_date matching; default is fine here.Final Answer:
Use ExternalTaskSensor with external_dag_id='dag_1', external_task_id='task_a', and default execution_date matching -> Option CQuick Check:
Default execution_date matching avoids deadlocks [OK]
- Shifting execution_date causing missed dependencies
- Ignoring execution_date alignment
- Misusing mode without fixing execution_date
Ready to prove it?
Pass the test and this pattern moves unknown
