Continuously service DAG processor IPC while parsers are active - #72008
Open
slice-soupam wants to merge 1 commit into
Open
Continuously service DAG processor IPC while parsers are active#72008slice-soupam wants to merge 1 commit into
slice-soupam wants to merge 1 commit into
Conversation
slice-soupam
requested review from
amoghrajesh,
ashb,
ephraimbuddy,
jedcunningham and
kaxil
as code owners
August 23, 2026 20:10
|
Congratulations on your first Pull Request and welcome to the Apache Airflow community! If you have any issues or are unsure about any anything please check our Contributors' Guide
|
Parser children that call Variable.get() or xcom_push() block on socket.recv() until the parent replies. Polling sockets only once per loop left those children stuck during bundle refresh and other long work, and unknown IPC types were dropped with no reply, which could pin a parser slot until timeout.
slice-soupam
force-pushed
the
service-dag-processor-ipc
branch
from
August 23, 2026 20:25
ee98712 to
d8c3830
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Parser children that call
Variable.get()orxcom_push()during parse or callbacks can pin a Dag-processor slot untildag_file_processor_timeout. This PR services IPC continuously while parsers are active, implementsSetXComon the Dag processor, and always replies to undecodable requests so a child cannot hang with no response.Problem
Two related gaps produce the same symptom: a parser child blocks on
socket.recv()and occupies a slot so other Dags go stale.1. Supported IPC is serviced too slowly
When a Dag file calls
Variable.get()orConnection.get()during parse, the forked child sends an IPC request and waits for the parent. The parent only called_service_processor_sockets()once per_run_parsing_loop()iteration. While the parent is in_refresh_dag_bundles(),_collect_results(), stale-Dag scans, or other long work, children wait.Airflow 2 did a direct metadata-DB read for those lookups, so this is a 3.x regression. Profiling of the Dag processor shows
_parse_file()time dominated by a singlesocket.recv()insideCommsDecoder._get_response().2. Unsupported IPC never gets a reply
A production failure callback called
ti.xcom_push(). The child sentSetXCom, which was not in the Dag processorToManagerunion.WatchedSubprocess.handle_requestsloggedUnable to decode messageand continued without sending a reply. The child hung untildag_file_processor_timeout(default 1200s), pinning a parser slot so other Dags stayed stale.SetXComis already implemented on the triggerer path. Dag-processor callbacks that usedxcom_push()in Airflow 2 silently lost that behavior after the IPC split.Any other unsupported type (
DeleteXCom,SucceedTask,DeferTask, …) has the same hang-with-no-reply failure mode.Proposed solution
Three layers, all required to close the hang:
dag-processor-ipcthread polls processor sockets for the entire parsing loop, so children get replies while the main thread is busy. The in-loop_service_processor_sockets()call is removed._LockedSelectorserializesselect/register/unregisterso the IPC thread and the main thread do not race on the shared selector. Timeout and orphan kills usekill(..., wait=False)so they send the signal without stealing that selector.SetXComis added toToManagerand handled with the existinghandle_set_xcomhelper (same as the triggerer). Any other undecodable frame getsErrorResponsewith the request id, so the child'sCommsDecoderraises immediately instead of hanging.DeleteXComand other task-lifecycle messages stay unsupported on purpose; they now fail fast rather than pin a slot.Test plan
TestHandleRequest.test_handle_requests_undecodable_message_sends_error— decode failure sendsErrorResponseinstead of dropping the frameTestDagFileProcessorProcess.test_handle_request_set_xcom— Dag processor persistsSetXComTestDagProcessingMessageTypes.test_to_manager_accepts_set_xcom/test_to_manager_rejects_unsupported_delete_xcomTestDagFileProcessor.test_variable_get_serviced_while_manager_is_busy— childVariable.get()is answered while the main thread is not pollingTestDagFileProcessorManager.test_ipc_service_thread_starts_and_stops/test_ipc_service_thread_polls_while_caller_is_blockedkill(SIGKILL, wait=False)