[ 
https://issues.apache.org/jira/browse/NIFI-16312?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Joe Witt updated NIFI-16312:
----------------------------
    Summary: Add command timeout to ExecuteProcess and ExecuteStreamCommand and 
fail when the command does not complete  (was: ExecuteProcess and 
ExecuteStreamCommand swallow interrupts and can report success)

> Add command timeout to ExecuteProcess and ExecuteStreamCommand and fail when 
> the command does not complete
> ----------------------------------------------------------------------------------------------------------
>
>                 Key: NIFI-16312
>                 URL: https://issues.apache.org/jira/browse/NIFI-16312
>             Project: Apache NiFi
>          Issue Type: Bug
>            Reporter: Joe Witt
>            Assignee: Joe Witt
>            Priority: Major
>
> ExecuteProcess and ExecuteStreamCommand wait for a child process on the 
> processor thread. Both catch InterruptedException and do not restore the 
> interrupt status. After that, they can continue as if the command completed 
> normally.
> ExecuteProcess (unbounded wait and batch sleep):
>     try {
>         longRunningProcess.get();
>     } catch (final InterruptedException ignored) {
>     }
>     try {
>         TimeUnit.NANOSECONDS.sleep(batchNanos);
>     } catch (final InterruptedException ignored) {
>     }
> If the wait is interrupted, the catch is empty. The processor then proceeds: 
> if stdout was written, the FlowFile is transferred to success. The interrupt 
> flag is cleared, so the framework cannot see that the worker was cancelled.
> ExecuteStreamCommand (both waitFor paths):
>     int exitCode;   // defaults to 0
>     try {
>         exitCode = process.waitFor();
>     } catch (InterruptedException e) {
>         logger.warn("Command Execution Process was interrupted", e);
>     }
> exitCode is an instance field that defaults to 0. If waitFor() is 
> interrupted, it is never assigned, so the command is treated as exit 0. 
> Routing then uses that status (output vs nonzero-status / execution.status 
> attribute).
> This ticket is interrupt handling only:
> - Call Thread.currentThread().interrupt() in every InterruptedException catch 
> in these two processors.
> - Do not treat an interrupted wait as a successful exit (ExecuteStreamCommand 
> must not keep exitCode 0; ExecuteProcess must not route partial output to 
> success as if the process finished).
> - Surefire tests using local commands (no Docker, no cloud).
> Out of scope: a Command Timeout / destroyForcibly property. ExecuteProcess 
> already has an in-code note that Future.get(timeout) should be used to avoid 
> waiting forever. That is a separate JIRA after this one, so timeout handling 
> does not also have to invent interrupt policy.
> Expected:
> - An interrupted wait restores the interrupt flag.
> - The session does not report a successful completed command.
> - Existing success/nonzero-exit tests still pass.
> Actual:
> - InterruptedException is ignored or logged, the flag is cleared, and 
> ExecuteStreamCommand can attribute execution.status=0.



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

Reply via email to