@@ -11204,4 +11204,127 @@ public void testBug70677() throws Exception {
1120411204 }
1120511205 }
1120611206 }
11207+
11208+ /**
11209+ * Test fix for Bug#23143279, CLIENT HANG WHEN LOADBALANCESTRATEGY IS BESTRESPONSETIME.
11210+ *
11211+ * @throws Exception
11212+ */
11213+ public void testBug23143279() throws Exception {
11214+ testBug23143279RunTest("random");
11215+ testBug23143279RunTest("bestResponseTime");
11216+ testBug23143279RunTest("serverAffinity");
11217+ testBug23143279RunTest("com.mysql.jdbc.SequentialBalanceStrategy");
11218+ }
11219+
11220+ private void testBug23143279RunTest(String lbStrategy) throws Exception {
11221+ final String defaultHost = getPropertiesFromTestsuiteUrl().getProperty(NonRegisteringDriver.HOST_PROPERTY_KEY);
11222+ final String defaultPort = getPropertiesFromTestsuiteUrl().getProperty(NonRegisteringDriver.PORT_PROPERTY_KEY);
11223+
11224+ final String host1 = "first";
11225+ final String host2 = "second";
11226+ final String host3 = "third";
11227+ final String host4 = "fourth";
11228+ final String hostPort4 = host4 + ":" + defaultPort;
11229+
11230+ final String uniqueId = String.valueOf(lbStrategy.substring(lbStrategy.lastIndexOf('.') + 1, lbStrategy.lastIndexOf('.') + 4)).toUpperCase();
11231+ final String connGroupName = "testBug23143279" + uniqueId;
11232+
11233+ final Properties props = new Properties();
11234+ props.setProperty("useSSL", "false");
11235+ props.setProperty("loadBalanceHostRemovalGracePeriod", "0");
11236+ props.setProperty("loadBalanceConnectionGroup", connGroupName);
11237+ props.setProperty("loadBalanceStrategy", lbStrategy);
11238+
11239+ System.out.println("\n\nTEST: " + lbStrategy);
11240+ System.out.println("********************************************************************************");
11241+ System.out.println("\tHosts group: " + connGroupName);
11242+
11243+ final MySQLConnection testConn = (MySQLConnection) getUnreliableLoadBalancedConnection(new String[] { host1, host2, host3 }, props,
11244+ new HashSet<String>(Arrays.asList(host2, host3)));
11245+ UnreliableSocketFactory.mapHost(host4, defaultHost);
11246+
11247+ System.out.println("\nStep 1: initial connection");
11248+ System.out.println("********************************************************************************");
11249+ System.out.println("\tHosts count: " + ConnectionGroupManager.getActiveHostCount(connGroupName));
11250+ System.out.println("\tHosts: " + ConnectionGroupManager.getActiveHostLists(connGroupName));
11251+ System.out.println("\tConnected to: " + testConn.getHostPortPair());
11252+ System.out.println("\tConnection id: " + testConn.getId());
11253+
11254+ assertEquals(host1 + ":" + defaultPort, testConn.getHostPortPair());
11255+
11256+ this.stmt.execute("KILL CONNECTION " + testConn.getId());
11257+ try {
11258+ testConn.createStatement().executeQuery("SELECT 1");
11259+ fail("Should have thrown an exception here.");
11260+ } catch (SQLException e) {
11261+ System.out.println(e.getMessage());
11262+ // Should be reconnected by now.
11263+ }
11264+
11265+ System.out.println("\nStep 2: after killing the active connection and having reconnected");
11266+ System.out.println("********************************************************************************");
11267+ System.out.println("\tHosts count: " + ConnectionGroupManager.getActiveHostCount(connGroupName));
11268+ System.out.println("\tHosts: " + ConnectionGroupManager.getActiveHostLists(connGroupName));
11269+ System.out.println("\tConnected to: " + testConn.getHostPortPair());
11270+ System.out.println("\tConnection id: " + testConn.getId());
11271+
11272+ assertEquals(host1 + ":" + defaultPort, testConn.getHostPortPair());
11273+
11274+ ConnectionGroupManager.addHost(connGroupName, hostPort4, true);
11275+
11276+ System.out.println("\nStep 3: after adding a new host");
11277+ System.out.println("********************************************************************************");
11278+ System.out.println("\tHosts count: " + ConnectionGroupManager.getActiveHostCount(connGroupName));
11279+ System.out.println("\tHosts: " + ConnectionGroupManager.getActiveHostLists(connGroupName));
11280+ System.out.println("\tConnected to: " + testConn.getHostPortPair());
11281+ System.out.println("\tConnection id: " + testConn.getId());
11282+
11283+ this.stmt.execute("KILL CONNECTION " + testConn.getId());
11284+ try {
11285+ testConn.createStatement().executeQuery("SELECT 1");
11286+ } catch (SQLException e) {
11287+ System.out.println(e.getMessage());
11288+ // Should be reconnected by now.
11289+ }
11290+
11291+ boolean connectedToHost1 = testConn.getHostPortPair().startsWith(host1);
11292+ assertEquals((connectedToHost1 ? host1 : host4) + ":" + defaultPort, testConn.getHostPortPair());
11293+
11294+ System.out.println("\nStep 4: after killing the active connection and having reconnected");
11295+ System.out.println("********************************************************************************");
11296+ System.out.println("\tHosts count: " + ConnectionGroupManager.getActiveHostCount(connGroupName));
11297+ System.out.println("\tHosts: " + ConnectionGroupManager.getActiveHostLists(connGroupName));
11298+ System.out.println("\tConnected to: " + testConn.getHostPortPair());
11299+ System.out.println("\tConnection id: " + testConn.getId());
11300+
11301+ final String hostToRemove = testConn.getHostPortPair();
11302+ ExecutorService executor = Executors.newSingleThreadExecutor();
11303+ Future<?> future = executor.submit(new Callable<Void>() {
11304+ public Void call() throws Exception {
11305+ ConnectionGroupManager.removeHost(connGroupName, hostToRemove, true);
11306+ return null;
11307+ }
11308+ });
11309+
11310+ try {
11311+ future.get(10, TimeUnit.SECONDS);
11312+ } catch (TimeoutException e) {
11313+ executor.shutdownNow();
11314+ fail("Failed to remove host and connect to a new one.\n"
11315+ + "WARNING: A ConcurrentModificationException on UnreliableSocketFactory can happen from now on.");
11316+ }
11317+ executor.shutdownNow();
11318+
11319+ System.out.println("\nStep 5: after removing the connected host [" + hostToRemove + "]");
11320+ System.out.println("********************************************************************************");
11321+ System.out.println("\tHosts count: " + ConnectionGroupManager.getActiveHostCount(connGroupName));
11322+ System.out.println("\tHosts: " + ConnectionGroupManager.getActiveHostLists(connGroupName));
11323+ System.out.println("\tConnected to: " + testConn.getHostPortPair());
11324+ System.out.println("\tConnection id: " + testConn.getId());
11325+
11326+ assertEquals((connectedToHost1 ? host4 : host1) + ":" + defaultPort, testConn.getHostPortPair());
11327+
11328+ testConn.close();
11329+ }
1120711330}
0 commit comments