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

Bob Paulin updated NIFI-16544:
------------------------------
    Description: 
When testing drain functionality on a Connector component I observed a hang on 
starting the non-source processors.  This was observed during the 
prepareForUpdate

```
{
            "tid": "853",
            "time": "2026-11-04T02:08:47.025510714Z",
            "virtual": true,
            "name": "",
            "state": "WAITING",
            "parkBlocker":

{               "object": 
"java.util.concurrent.CompletableFuture$Signaller@5506df48"             }

,
            "stack": [
              "java.base\/java.lang.VirtualThread.park(VirtualThread.java:745)",
              
"java.base\/java.lang.System$1.parkVirtualThread(System.java:2285)",
              
"java.base\/java.util.concurrent.locks.LockSupport.park(LockSupport.java:221)",
              
"java.base\/java.util.concurrent.CompletableFuture$Signaller.block(CompletableFuture.java:1885)",
              
"java.base\/java.util.concurrent.ForkJoinPool.unmanagedBlock(ForkJoinPool.java:4364)",
              
"java.base\/java.util.concurrent.ForkJoinPool.managedBlock(ForkJoinPool.java:4310)",
              
"java.base\/java.util.concurrent.CompletableFuture.waitingGet(CompletableFuture.java:1919)",
              
"java.base\/java.util.concurrent.CompletableFuture.get(CompletableFuture.java:2093)",
              
"org.apache.nifi.components.connector.AbstractConnector.startNonSourceComponents(AbstractConnector.java:294)",
              
"org.apache.nifi.components.connector.AbstractConnector.lambda$drainFlowFiles$3(AbstractConnector.java:207)",
              "java.base\/java.lang.VirtualThread.run(VirtualThread.java:460)"
            ]
          },

```

The hang started showing up because I'm looking to wait on that future to do 
some processing in prepareForUpdate

Exception

```


org.apache.nifi.components.connector.FlowUpdateException: Timed out waiting for 
all FlowFiles to drain from the flow
 
at 
com.somepackage.runtime.connectors.myconnector.MyConnector.awaitUrlDrain(MyConnector.java:241)
 
at 
com.somepackage.runtime.connectors.myconnector.MyConnector.prepareForUpdate(MyConnector.java:173)
 
at 
org.apache.nifi.components.connector.StandardConnectorNode.prepareForUpdate(StandardConnectorNode.java:309)
 
at 
org.apache.nifi.components.connector.StandardConnectorRepository.updateConnector(StandardConnectorRepository.java:671)
 
at 
org.apache.nifi.components.connector.StandardConnectorRepository.lambda$applyUpdate$0(StandardConnectorRepository.java:661)
 
at org.apache.nifi.engine.FlowEngine.lambda$wrap$1(FlowEngine.java:105)
 
at 
java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:545)
 
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:328)
 
at 
java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:309)
 
at 
java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1090)
 
at 
java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:614)
 
at java.base/java.lang.Thread.run(Thread.java:1474)
 
Caused by: java.util.concurrent.TimeoutException
 
at 
java.base/java.util.concurrent.CompletableFuture.timedGet(CompletableFuture.java:1981)
 
at 
java.base/java.util.concurrent.CompletableFuture.get(CompletableFuture.java:2116)
 
at 
com.somepackage.runtime.connectors.myconnector.MyConnector.awaitUrlDrain(MyConnector.java:232)
 
... 11 common frames omitted

```




When a Processor or Stateless Group was not STOPPED, the start request
logged a warning and returned without invoking the SchedulingAgentCallback.
The Future returned to the caller was never completed, so any caller
blocking on it, such as a Connector draining FlowFiles, hung indefinitely.
 
Add SchedulingAgentCallback.onStartDeclined(ScheduledState) with a no-op
default. StandardProcessorNode and StandardStatelessGroupNode now invoke
it whenever they decline a start. The scheduler completes the Future for
an already running or starting component, and fails it for a disabled
processor or a stopping Stateless Group.

  was:
When testing drain functionality on a Connector component I observed a hang on 
starting the non-source processors.  This was observed during the drain 
function as well as during a drain called during prepareForUpdate



```
{
            "tid": "853",
            "time": "2026-11-04T02:08:47.025510714Z",
            "virtual": true,
            "name": "",
            "state": "WAITING",
            "parkBlocker": {
              "object": 
"java.util.concurrent.CompletableFuture$Signaller@5506df48"
            },
            "stack": [
              "java.base\/java.lang.VirtualThread.park(VirtualThread.java:745)",
              
"java.base\/java.lang.System$1.parkVirtualThread(System.java:2285)",
              
"java.base\/java.util.concurrent.locks.LockSupport.park(LockSupport.java:221)",
              
"java.base\/java.util.concurrent.CompletableFuture$Signaller.block(CompletableFuture.java:1885)",
              
"java.base\/java.util.concurrent.ForkJoinPool.unmanagedBlock(ForkJoinPool.java:4364)",
              
"java.base\/java.util.concurrent.ForkJoinPool.managedBlock(ForkJoinPool.java:4310)",
              
"java.base\/java.util.concurrent.CompletableFuture.waitingGet(CompletableFuture.java:1919)",
              
"java.base\/java.util.concurrent.CompletableFuture.get(CompletableFuture.java:2093)",
              
"org.apache.nifi.components.connector.AbstractConnector.startNonSourceComponents(AbstractConnector.java:294)",
              
"org.apache.nifi.components.connector.AbstractConnector.lambda$drainFlowFiles$3(AbstractConnector.java:207)",
              "java.base\/java.lang.VirtualThread.run(VirtualThread.java:460)"
            ]
          },

```


When a Processor or Stateless Group was not STOPPED, the start request
logged a warning and returned without invoking the SchedulingAgentCallback.
The Future returned to the caller was never completed, so any caller
blocking on it, such as a Connector draining FlowFiles, hung indefinitely.
 
Add SchedulingAgentCallback.onStartDeclined(ScheduledState) with a no-op
default. StandardProcessorNode and StandardStatelessGroupNode now invoke
it whenever they decline a start. The scheduler completes the Future for
an already running or starting component, and fails it for a disabled
processor or a stopping Stateless Group.


> Complete start Futures when Processor or Stateless Group declines start
> -----------------------------------------------------------------------
>
>                 Key: NIFI-16544
>                 URL: https://issues.apache.org/jira/browse/NIFI-16544
>             Project: Apache NiFi
>          Issue Type: Bug
>            Reporter: Bob Paulin
>            Priority: Major
>          Time Spent: 10m
>  Remaining Estimate: 0h
>
> When testing drain functionality on a Connector component I observed a hang 
> on starting the non-source processors.  This was observed during the 
> prepareForUpdate
> ```
> {
>             "tid": "853",
>             "time": "2026-11-04T02:08:47.025510714Z",
>             "virtual": true,
>             "name": "",
>             "state": "WAITING",
>             "parkBlocker":
> {               "object": 
> "java.util.concurrent.CompletableFuture$Signaller@5506df48"             }
> ,
>             "stack": [
>               
> "java.base\/java.lang.VirtualThread.park(VirtualThread.java:745)",
>               
> "java.base\/java.lang.System$1.parkVirtualThread(System.java:2285)",
>               
> "java.base\/java.util.concurrent.locks.LockSupport.park(LockSupport.java:221)",
>               
> "java.base\/java.util.concurrent.CompletableFuture$Signaller.block(CompletableFuture.java:1885)",
>               
> "java.base\/java.util.concurrent.ForkJoinPool.unmanagedBlock(ForkJoinPool.java:4364)",
>               
> "java.base\/java.util.concurrent.ForkJoinPool.managedBlock(ForkJoinPool.java:4310)",
>               
> "java.base\/java.util.concurrent.CompletableFuture.waitingGet(CompletableFuture.java:1919)",
>               
> "java.base\/java.util.concurrent.CompletableFuture.get(CompletableFuture.java:2093)",
>               
> "org.apache.nifi.components.connector.AbstractConnector.startNonSourceComponents(AbstractConnector.java:294)",
>               
> "org.apache.nifi.components.connector.AbstractConnector.lambda$drainFlowFiles$3(AbstractConnector.java:207)",
>               "java.base\/java.lang.VirtualThread.run(VirtualThread.java:460)"
>             ]
>           },
> ```
> The hang started showing up because I'm looking to wait on that future to do 
> some processing in prepareForUpdate
> Exception
> ```
> org.apache.nifi.components.connector.FlowUpdateException: Timed out waiting 
> for all FlowFiles to drain from the flow
>  
> at 
> com.somepackage.runtime.connectors.myconnector.MyConnector.awaitUrlDrain(MyConnector.java:241)
>  
> at 
> com.somepackage.runtime.connectors.myconnector.MyConnector.prepareForUpdate(MyConnector.java:173)
>  
> at 
> org.apache.nifi.components.connector.StandardConnectorNode.prepareForUpdate(StandardConnectorNode.java:309)
>  
> at 
> org.apache.nifi.components.connector.StandardConnectorRepository.updateConnector(StandardConnectorRepository.java:671)
>  
> at 
> org.apache.nifi.components.connector.StandardConnectorRepository.lambda$applyUpdate$0(StandardConnectorRepository.java:661)
>  
> at org.apache.nifi.engine.FlowEngine.lambda$wrap$1(FlowEngine.java:105)
>  
> at 
> java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:545)
>  
> at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:328)
>  
> at 
> java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:309)
>  
> at 
> java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1090)
>  
> at 
> java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:614)
>  
> at java.base/java.lang.Thread.run(Thread.java:1474)
>  
> Caused by: java.util.concurrent.TimeoutException
>  
> at 
> java.base/java.util.concurrent.CompletableFuture.timedGet(CompletableFuture.java:1981)
>  
> at 
> java.base/java.util.concurrent.CompletableFuture.get(CompletableFuture.java:2116)
>  
> at 
> com.somepackage.runtime.connectors.myconnector.MyConnector.awaitUrlDrain(MyConnector.java:232)
>  
> ... 11 common frames omitted
> ```
> When a Processor or Stateless Group was not STOPPED, the start request
> logged a warning and returned without invoking the SchedulingAgentCallback.
> The Future returned to the caller was never completed, so any caller
> blocking on it, such as a Connector draining FlowFiles, hung indefinitely.
>  
> Add SchedulingAgentCallback.onStartDeclined(ScheduledState) with a no-op
> default. StandardProcessorNode and StandardStatelessGroupNode now invoke
> it whenever they decline a start. The scheduler completes the Future for
> an already running or starting component, and fails it for a disabled
> processor or a stopping Stateless Group.



--
This message was sent by Atlassian Jira
(v10.3.26#10030026)

Reply via email to