I am running a long-running Python script inside an Apache Airflow DAG using BashOperator. When I manually stop the task using "Mark as Failed" or "Mark as Success", Airflow sends a SIGTERM signal to the process.
However, I am unable to properly catch SIGTERM and execute cleanup logic before the process is forcefully terminated.
I tried using signal.signal()
to handle SIGTERM:
import sys
import time
import signal
def handle_exit(signum, frame):
print("[ALERT] Received SIGTERM! Stopping...")
sys.exit(1)
signal.signal(signal.SIGINT, handle_exit) # To handle Ctrl+C
signal.signal(signal.SIGTERM, handle_exit) # To handle Airflow termination
while True:
print("[INFO] Running...")
time.sleep(2)
Still, the [ALERT] Received SIGTERM! message does not appear in the logs, meaning the signal isn't caught before termination.
Here is the airflow log:
[2025-04-02, 19:16:15 IST] {taskinstance.py:1157} INFO - Dependencies all met for dep_context=non-requeueable deps ti=<TaskInstance: dag_dependency_check_parent.stop_check manual__2025-04-02T13:46:06.768233+00:00 [queued]>
[2025-04-02, 19:16:15 IST] {taskinstance.py:1157} INFO - Dependencies all met for dep_context=requeueable deps ti=<TaskInstance: dag_dependency_check_parent.stop_check manual__2025-04-02T13:46:06.768233+00:00 [queued]>
[2025-04-02, 19:16:15 IST] {taskinstance.py:1359} INFO - Starting attempt 1 of 1
[2025-04-02, 19:16:15 IST] {taskinstance.py:1380} INFO - Executing <Task(BashOperator): stop_check> on 2025-04-02 13:46:06.768233+00:00
[2025-04-02, 19:16:15 IST] {standard_task_runner.py:57} INFO - Started process 4615 to run task
[2025-04-02, 19:16:15 IST] {standard_task_runner.py:84} INFO - Running: ['airflow', 'tasks', 'run', 'dag_dependency_check_parent', 'stop_check', 'manual__2025-04-02T13:46:06.768233+00:00', '--job-id', '27296', '--raw', '--subdir', 'DAGS_FOLDER/dag_dependency_check_parent.py', '--cfg-path', '/tmp/tmpxut1ufvt']
[2025-04-02, 19:16:15 IST] {standard_task_runner.py:85} INFO - Job 27296: Subtask stop_check
[2025-04-02, 19:16:15 IST] {task_command.py:415} INFO - Running <TaskInstance: dag_dependency_check_parent.stop_check manual__2025-04-02T13:46:06.768233+00:00 [running]> on host a9c63f287b52
[2025-04-02, 19:16:15 IST] {taskinstance.py:1660} INFO - Exporting env vars: AIRFLOW_CTX_DAG_OWNER='arudsekabs' AIRFLOW_CTX_DAG_ID='dag_dependency_check_parent' AIRFLOW_CTX_TASK_ID='stop_check' AIRFLOW_CTX_EXECUTION_DATE='2025-04-02T13:46:06.768233+00:00' AIRFLOW_CTX_TRY_NUMBER='1' AIRFLOW_CTX_DAG_RUN_ID='manual__2025-04-02T13:46:06.768233+00:00'
[2025-04-02, 19:16:15 IST] {subprocess.py:63} INFO - Tmp dir root location: /tmp
[2025-04-02, 19:16:15 IST] {subprocess.py:75} INFO - Running command: ['/usr/bin/bash', '-c', 'python3 -u /opt/airflow/jobs/arudsekabs_stop_test.py']
[2025-04-02, 19:16:15 IST] {subprocess.py:86} INFO - Output:
[2025-04-02, 19:16:15 IST] {subprocess.py:93} INFO - [INFO] Running...
[2025-04-02, 19:16:17 IST] {subprocess.py:93} INFO - [INFO] Running...
[2025-04-02, 19:16:19 IST] {subprocess.py:93} INFO - [INFO] Running...
[2025-04-02, 19:16:21 IST] {subprocess.py:93} INFO - [INFO] Running...
[2025-04-02, 19:16:23 IST] {subprocess.py:93} INFO - [INFO] Running...
[2025-04-02, 19:16:25 IST] {subprocess.py:93} INFO - [INFO] Running...