diff options
author | Harald Musum <musum@verizonmedia.com> | 2020-05-18 14:55:12 +0200 |
---|---|---|
committer | Harald Musum <musum@verizonmedia.com> | 2020-05-18 14:55:12 +0200 |
commit | 800566292b15b2a52eeb6511d0de9b3ebe121f17 (patch) | |
tree | 998d18ad4e920e7152978ac0a3ee525369511f46 | |
parent | b081282192342f0a88e422b7aec945df279de644 (diff) |
Swith to a new connection if possible when asked to do so
Try to avoid reusing the same connection we want to avoid using,
only using it when there is just one source
7 files changed, 52 insertions, 21 deletions
diff --git a/config/src/main/java/com/yahoo/config/subscription/impl/MockConnection.java b/config/src/main/java/com/yahoo/config/subscription/impl/MockConnection.java index 58eed7f9e78..3a06aa02dc0 100644 --- a/config/src/main/java/com/yahoo/config/subscription/impl/MockConnection.java +++ b/config/src/main/java/com/yahoo/config/subscription/impl/MockConnection.java @@ -7,6 +7,7 @@ import com.yahoo.jrt.Supervisor; import com.yahoo.vespa.config.ConfigPayload; import com.yahoo.vespa.config.Connection; import com.yahoo.vespa.config.ConnectionPool; +import com.yahoo.vespa.config.JRTConnection; import com.yahoo.vespa.config.protocol.JRTServerConfigRequestV3; import com.yahoo.vespa.config.protocol.Payload; import com.yahoo.vespa.config.util.ConfigUtils; @@ -87,9 +88,7 @@ public class MockConnection implements ConnectionPool, com.yahoo.vespa.config.Co } @Override - public Connection setNewCurrentConnection() { - return this; - } + public Connection switchConnection() { return this; } @Override public int getSize() { diff --git a/config/src/main/java/com/yahoo/vespa/config/ConnectionPool.java b/config/src/main/java/com/yahoo/vespa/config/ConnectionPool.java index 5a6f8a8848b..949cc16ce68 100644 --- a/config/src/main/java/com/yahoo/vespa/config/ConnectionPool.java +++ b/config/src/main/java/com/yahoo/vespa/config/ConnectionPool.java @@ -10,11 +10,32 @@ public interface ConnectionPool { void close(); + /** + * Sets the supplied Connection to have an error, implementations are expected to call + * {@link #switchConnection()} after setting state for the supplied Connection. + * + */ void setError(Connection connection, int i); Connection getCurrent(); - Connection setNewCurrentConnection(); + /** + * Switches to another JRTConnection instance by randomly choosing + * from the available sources, disregarding the current connection if there is + * more than one source. Returns the resulting Connection. See also {@link #setError(Connection, int)} + * + * @return a JRTConnection + */ + Connection switchConnection(); + + /** + * Sets the current JRTConnection instance by randomly choosing + * from the available sources and returns the result. + * + * @return a JRTConnection + */ + @Deprecated + default Connection setNewCurrentConnection() { return switchConnection(); }; int getSize(); diff --git a/config/src/main/java/com/yahoo/vespa/config/JRTConnectionPool.java b/config/src/main/java/com/yahoo/vespa/config/JRTConnectionPool.java index 2c1d00f295e..da77abbb648 100644 --- a/config/src/main/java/com/yahoo/vespa/config/JRTConnectionPool.java +++ b/config/src/main/java/com/yahoo/vespa/config/JRTConnectionPool.java @@ -13,6 +13,7 @@ import java.util.concurrent.ThreadLocalRandom; import java.util.logging.Logger; import static java.util.logging.Level.FINE; +import static java.util.logging.Level.INFO; /** * A pool of JRT connections to a config source (either a config server or a config proxy). @@ -53,7 +54,7 @@ public class JRTConnectionPool implements ConnectionPool { connections.put(address, new JRTConnection(address, supervisor)); } } - setNewCurrentConnection(); + initialize(); } /** @@ -65,14 +66,27 @@ public class JRTConnectionPool implements ConnectionPool { return currentConnection; } - /** - * Returns and set the current JRTConnection instance by randomly choosing - * from the available sources (this means that you might end up using - * the same connection). - * - * @return a JRTConnection - */ + @Override + public synchronized JRTConnection switchConnection() { + List<JRTConnection> sources = getSources(); + if (sources.size() > 1) { + Connection previousConnection = currentConnection; + List<JRTConnection> sourcesWithoutCurrent = new ArrayList<>(); + sources.stream() + .filter(source -> ! source.equals(currentConnection)) + .forEach(sourcesWithoutCurrent::add); + currentConnection = sourcesWithoutCurrent.get(ThreadLocalRandom.current().nextInt(0, sourcesWithoutCurrent.size())); + log.log(INFO, () -> "Switching from " + previousConnection + " to " + currentConnection); + } + return currentConnection; + } + + @Deprecated public synchronized JRTConnection setNewCurrentConnection() { + return initialize(); + } + + public synchronized JRTConnection initialize() { List<JRTConnection> sources = getSources(); currentConnection = sources.get(ThreadLocalRandom.current().nextInt(0, sources.size())); log.log(FINE, () -> "Choosing new connection: " + currentConnection); @@ -94,7 +108,7 @@ public class JRTConnectionPool implements ConnectionPool { @Override public void setError(Connection connection, int errorCode) { connection.setError(errorCode); - setNewCurrentConnection(); + switchConnection(); } public JRTConnectionPool updateSources(List<String> addresses) { diff --git a/config/src/test/java/com/yahoo/vespa/config/JRTConnectionPoolTest.java b/config/src/test/java/com/yahoo/vespa/config/JRTConnectionPoolTest.java index cc46301e869..56f40daf0fd 100644 --- a/config/src/test/java/com/yahoo/vespa/config/JRTConnectionPoolTest.java +++ b/config/src/test/java/com/yahoo/vespa/config/JRTConnectionPoolTest.java @@ -29,7 +29,7 @@ public class JRTConnectionPoolTest { Map<String, Integer> sourceOccurrences = new HashMap<>(); for (int i = 0; i < 1000; i++) { - final String address = sourcePool.setNewCurrentConnection().getAddress(); + final String address = sourcePool.switchConnection().getAddress(); if (sourceOccurrences.containsKey(address)) { sourceOccurrences.put(address, sourceOccurrences.get(address) + 1); } else { @@ -57,7 +57,7 @@ public class JRTConnectionPoolTest { int count = 1000; for (int i = 0; i < count; i++) { - String address = sourcePool.setNewCurrentConnection().getAddress(); + String address = sourcePool.switchConnection().getAddress(); if (timesUsed.containsKey(address)) { int times = timesUsed.get(address); timesUsed.put(address, times + 1); diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/filedistribution/FileServer.java b/configserver/src/main/java/com/yahoo/vespa/config/server/filedistribution/FileServer.java index 805ee2bef95..23e8ac18501 100644 --- a/configserver/src/main/java/com/yahoo/vespa/config/server/filedistribution/FileServer.java +++ b/configserver/src/main/java/com/yahoo/vespa/config/server/filedistribution/FileServer.java @@ -222,7 +222,7 @@ public class FileServer { public Connection getCurrent() { return null; } @Override - public Connection setNewCurrentConnection() { return null; } + public Connection switchConnection() { return null; } @Override public int getSize() { return 0; } diff --git a/filedistribution/src/main/java/com/yahoo/vespa/filedistribution/FileReferenceDownloader.java b/filedistribution/src/main/java/com/yahoo/vespa/filedistribution/FileReferenceDownloader.java index 4ee9eacc2be..6b8a3802a2f 100644 --- a/filedistribution/src/main/java/com/yahoo/vespa/filedistribution/FileReferenceDownloader.java +++ b/filedistribution/src/main/java/com/yahoo/vespa/filedistribution/FileReferenceDownloader.java @@ -20,7 +20,6 @@ import java.util.Optional; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; -import java.util.logging.Level; import java.util.logging.Logger; /** @@ -125,7 +124,7 @@ public class FileReferenceDownloader { return true; } else { log.log(logLevel, "File reference '" + fileReference + "' not found for " + connection.getAddress()); - connectionPool.setNewCurrentConnection(); + connectionPool.switchConnection(); return false; } } else { diff --git a/filedistribution/src/test/java/com/yahoo/vespa/filedistribution/FileDownloaderTest.java b/filedistribution/src/test/java/com/yahoo/vespa/filedistribution/FileDownloaderTest.java index 52d8507acea..e35e75ce6cc 100644 --- a/filedistribution/src/test/java/com/yahoo/vespa/filedistribution/FileDownloaderTest.java +++ b/filedistribution/src/test/java/com/yahoo/vespa/filedistribution/FileDownloaderTest.java @@ -341,9 +341,7 @@ public class FileDownloaderTest { } @Override - public Connection setNewCurrentConnection() { - return this; - } + public Connection switchConnection() { return this; } @Override public int getSize() { |