From f0fab484e30a5b85209067a392181584b590b7ad Mon Sep 17 00:00:00 2001 From: functioner Date: Sat, 27 Nov 2021 00:23:11 -0500 Subject: [PATCH 1/2] ZOOKEEPER-4419: The potential exception in Learner.connectToLeader may cause unnecessary re-election or service delay --- .../java/org/apache/zookeeper/server/quorum/Learner.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/zookeeper-server/src/main/java/org/apache/zookeeper/server/quorum/Learner.java b/zookeeper-server/src/main/java/org/apache/zookeeper/server/quorum/Learner.java index adf0ef6e510..a893cded3af 100644 --- a/zookeeper-server/src/main/java/org/apache/zookeeper/server/quorum/Learner.java +++ b/zookeeper-server/src/main/java/org/apache/zookeeper/server/quorum/Learner.java @@ -396,7 +396,7 @@ public void run() { } private Socket connectToLeader() throws IOException, X509Exception, InterruptedException { - Socket sock = createSocket(); + Socket sock = null; // leader connection timeout defaults to tickTime * initLimit int connectTimeout = self.tickTime * self.initLimit; @@ -410,8 +410,12 @@ private Socket connectToLeader() throws IOException, X509Exception, InterruptedE int remainingTimeout; long startNanoTime = nanoTime(); - for (int tries = 0; tries < 5 && socket.get() == null; tries++) { + for (int tries = 0; tries < 5; tries++) { try { + sock = createSocket(); + if (socket.get() == null) { + continue; + } // recalculate the init limit time because retries sleep for 1000 milliseconds remainingTimeout = connectTimeout - (int) ((nanoTime() - startNanoTime) / 1_000_000); if (remainingTimeout <= 0) { @@ -451,7 +455,6 @@ private Socket connectToLeader() throws IOException, X509Exception, InterruptedE remainingTimeout, address, e); - sock = createSocket(); } } Thread.sleep(leaderConnectDelayDuringRetryMs); From 8d130a59592738f3125e386cf2ff80308eb257f5 Mon Sep 17 00:00:00 2001 From: functioner Date: Sun, 28 Jun 2026 19:50:27 -0700 Subject: [PATCH 2/2] update --- .../zookeeper/server/quorum/Learner.java | 39 ++++++++----------- 1 file changed, 16 insertions(+), 23 deletions(-) diff --git a/zookeeper-server/src/main/java/org/apache/zookeeper/server/quorum/Learner.java b/zookeeper-server/src/main/java/org/apache/zookeeper/server/quorum/Learner.java index a893cded3af..c08744c692e 100644 --- a/zookeeper-server/src/main/java/org/apache/zookeeper/server/quorum/Learner.java +++ b/zookeeper-server/src/main/java/org/apache/zookeeper/server/quorum/Learner.java @@ -413,9 +413,7 @@ private Socket connectToLeader() throws IOException, X509Exception, InterruptedE for (int tries = 0; tries < 5; tries++) { try { sock = createSocket(); - if (socket.get() == null) { - continue; - } + // recalculate the init limit time because retries sleep for 1000 milliseconds remainingTimeout = connectTimeout - (int) ((nanoTime() - startNanoTime) / 1_000_000); if (remainingTimeout <= 0) { @@ -427,34 +425,29 @@ private Socket connectToLeader() throws IOException, X509Exception, InterruptedE if (self.isSslQuorum()) { ((SSLSocket) sock).startHandshake(); } - sock.setTcpNoDelay(nodelay); - break; } catch (IOException e) { + // close failed socket before retrying + if (sock != null) { + try { + sock.close(); + } catch (IOException closeException) { + LOG.debug("Failed to close socket after connection failure", closeException); + } + sock = null; + } remainingTimeout = connectTimeout - (int) ((nanoTime() - startNanoTime) / 1_000_000); if (remainingTimeout <= leaderConnectDelayDuringRetryMs) { - LOG.error( - "Unexpected exception, connectToLeader exceeded. tries={}, remaining init limit={}, connecting to {}", - tries, - remainingTimeout, - address, - e); + LOG.error("Unexpected exception, connectToLeader exceeded. tries={}, remaining init limit={}, connecting to {}", + tries, remainingTimeout, address, e); throw e; } else if (tries >= 4) { - LOG.error( - "Unexpected exception, retries exceeded. tries={}, remaining init limit={}, connecting to {}", - tries, - remainingTimeout, - address, - e); + LOG.error("Unexpected exception, retries exceeded. tries={}, remaining init limit={}, connecting to {}", + tries, remainingTimeout, address, e); throw e; } else { - LOG.warn( - "Unexpected exception, tries={}, remaining init limit={}, connecting to {}", - tries, - remainingTimeout, - address, - e); + LOG.warn("Unexpected exception, tries={}, remaining init limit={}, connecting to {}", + tries, remainingTimeout, address, e); } } Thread.sleep(leaderConnectDelayDuringRetryMs);