Martijn Visser created FLINK-40078:
--------------------------------------

             Summary: Lost non-loss-tolerant OperatorEvent to an 
already-failing task triggers a failover that masks the original failure cause
                 Key: FLINK-40078
                 URL: https://issues.apache.org/jira/browse/FLINK-40078
             Project: Flink
          Issue Type: Bug
            Reporter: Martijn Visser


When an OperatorCoordinator sends an event to a subtask that has just failed 
for an application reason, the delivery fails with {{TaskNotRunningException}} 
({{Task.deliverOperatorEvent}}). Because the event is not loss-tolerant, 
{{SubtaskGatewayImpl.sendEvent}} escalates this into

{code}
org.apache.flink.util.FlinkException: An OperatorEvent from an 
OperatorCoordinator to a task was lost. Triggering task failover to ensure 
consistency. Event: '[NoMoreSplitEvent]', ...
{code}

and triggers a task failover. Under {{NoRestartBackoffTimeStrategy}} that 
lost-event failover can win the race to the scheduler and become the job's 
reported terminal failure cause, completely replacing the original application 
error in the cause chain (the coordinator is co-located with the JobMaster, so 
its failure path can reach the scheduler faster than the failed task's own 
failure RPC).

The consequence is that a user debugging a failed job sees "An OperatorEvent 
... was lost. Triggering task failover to ensure consistency" instead of their 
actual error. This is general: any coordinator event in flight at the moment a 
task fails for an application reason can mask that failure. It was observed 
concretely in FLINK-40077, where a {{NoMoreSplitsEvent}} in flight to a task 
that intentionally failed on the NOT NULL enforcer replaced the enforcer error 
as the reported cause (there it was worked around in the test scaffolding; this 
ticket is about the runtime behavior itself).

The escalation mechanism already has an escape hatch: on 
{{TaskNotRunningException}}, {{SubtaskGatewayImpl}} returns without failover 
when {{evt.isLossTolerant()}} is true. {{NoMoreSplitsEvent}} is currently not 
marked loss-tolerant.

Possible directions (needs input from runtime/coordination owners, as this 
touches checkpoint/failover consistency semantics):
* Mark {{NoMoreSplitsEvent}} loss-tolerant, since a task that is FAILED or 
FINISHED has no further use for it.
* More generally, suppress the redundant lost-event failover when the target 
task is already failing/failed for another reason, so the original cause is 
preserved.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to