Run AsyncSshHandler.onOpenComplete() on event loop 24/102724/3
authorRobert Varga <robert.varga@pantheon.tech>
Tue, 18 Oct 2022 11:24:39 +0000 (13:24 +0200)
committerRobert Varga <robert.varga@pantheon.tech>
Tue, 18 Oct 2022 11:57:25 +0000 (13:57 +0200)
onOpenComplete() runs ctx.fireChannelActive(), which in turn talks to
other handlers. Netty silently delays the invocation if it is called
from a different thread.

Make sure we run onOpenComplete() on the appropriate executor, so that
the state transition and handler updates run synchronously.

JIRA: NETCONF-905
Change-Id: Id8c2f4cb1e045d5d5bb446801deec341ccb27e87
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
netconf/netconf-netty-util/src/main/java/org/opendaylight/netconf/nettyutil/handler/ssh/client/AsyncSshHandler.java

index e8f128c34734d14e2820da7edac2a728356906a8..5eaacb2d43fae05795cb788ba901dc39430d8cc6 100644 (file)
@@ -182,9 +182,12 @@ public final class AsyncSshHandler extends ChannelOutboundHandlerAdapter {
             return;
         }
 
-        openFuture.addListener(future -> onOpenComplete(future, ctx));
+        openFuture.addListener(future -> ctx.executor().execute(() -> onOpenComplete(future, ctx)));
     }
 
+    // This callback has to run on the channel's executor because it runs fireChannelActive(), which needs to be
+    // delivered synchronously. If we were to execute on some other thread we would end up delaying the event,
+    // potentially creating havoc in the pipeline.
     private synchronized void onOpenComplete(final OpenFuture openFuture, final ChannelHandlerContext ctx) {
         final var cause = openFuture.getException();
         if (cause != null) {