From 61838920ed997b3389973c9761662a6c57a3c7d4 Mon Sep 17 00:00:00 2001 From: chimp1984 Date: Tue, 28 Apr 2020 15:20:31 -0500 Subject: [PATCH] Fix issue with shutdown The getAllConnections() call in the while loop always returned the same number of nodes so the timeout of 15 sec was always triggered. We now wait for the shutdown handlers of the connections and if all are called we run our handler. If it takes longer as our timeout of 3 sec. the shutdown handler gets called by the timeout. --- .../bisq/network/p2p/network/NetworkNode.java | 45 ++++++++++--------- 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/p2p/src/main/java/bisq/network/p2p/network/NetworkNode.java b/p2p/src/main/java/bisq/network/p2p/network/NetworkNode.java index f924669b7d..58cd7a210b 100644 --- a/p2p/src/main/java/bisq/network/p2p/network/NetworkNode.java +++ b/p2p/src/main/java/bisq/network/p2p/network/NetworkNode.java @@ -19,6 +19,7 @@ package bisq.network.p2p.network; import bisq.network.p2p.NodeAddress; +import bisq.common.Timer; import bisq.common.UserThread; import bisq.common.proto.network.NetworkEnvelope; import bisq.common.proto.network.NetworkProtoResolver; @@ -36,9 +37,6 @@ import javafx.beans.property.ObjectProperty; import javafx.beans.property.ReadOnlyObjectProperty; import javafx.beans.property.SimpleObjectProperty; -import java.time.Duration; -import java.time.LocalTime; - import java.net.ConnectException; import java.net.ServerSocket; import java.net.Socket; @@ -51,6 +49,7 @@ import java.util.Set; import java.util.concurrent.CopyOnWriteArraySet; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; +import java.util.concurrent.atomic.AtomicInteger; import java.util.stream.Collectors; import org.slf4j.Logger; @@ -333,27 +332,29 @@ public abstract class NetworkNode implements MessageListener { server = null; } - getAllConnections().parallelStream().forEach(c -> c.shutDown(CloseConnectionReason.APP_SHUT_DOWN)); - - // wait for connections to actually close, c.shutDown may create threads to actually close connections... - LocalTime timeout = LocalTime.now().plus(Duration.ofSeconds(15)); - while (!getAllConnections().isEmpty()) { - // check timeout - if (timeout.isBefore(LocalTime.now())) { - log.error("Could not close all connections within timeout (" + getAllConnections().size() + " connections remaining). Moving on."); - break; + Set allConnections = getAllConnections(); + int numConnections = allConnections.size(); + log.info("Shutdown {} connections", numConnections); + AtomicInteger shutdownCompleted = new AtomicInteger(); + Timer timeoutHandler = UserThread.runAfter(() -> { + if (shutDownCompleteHandler != null) { + log.info("Shutdown completed due timeout"); + shutDownCompleteHandler.run(); } - try { - // reduce system load - Thread.sleep(10); - } catch (InterruptedException e) { - // ignore - } - } - - log.debug("NetworkNode shutdown complete"); + }, 3); + allConnections.forEach(c -> c.shutDown(CloseConnectionReason.APP_SHUT_DOWN, + () -> { + shutdownCompleted.getAndIncrement(); + log.info("Shutdown o fnode {} completed", c.getPeersNodeAddressOptional()); + if (shutdownCompleted.get() == numConnections) { + log.info("Shutdown completed with all connections closed"); + timeoutHandler.stop(); + if (shutDownCompleteHandler != null) { + shutDownCompleteHandler.run(); + } + } + })); } - if (shutDownCompleteHandler != null) shutDownCompleteHandler.run(); }