Skip to content

Commit 00bb57d

Browse files
SNOW-1943242: Recover from shutdown HTTP connection manager
1 parent dcb60b2 commit 00bb57d

2 files changed

Lines changed: 50 additions & 2 deletions

File tree

src/main/java/net/snowflake/client/core/HttpUtil.java

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import java.io.InputStream;
1818
import java.io.PrintWriter;
1919
import java.io.StringWriter;
20+
import java.lang.reflect.Field;
2021
import java.net.InetSocketAddress;
2122
import java.net.Proxy;
2223
import java.net.Socket;
@@ -497,8 +498,32 @@ public static CloseableHttpClient initHttpClientWithoutDecompression(
497498
*/
498499
public static CloseableHttpClient initHttpClient(HttpClientSettingsKey key, File ocspCacheFile) {
499500
updateRoutePlanner(key);
500-
return httpClient.computeIfAbsent(
501-
key, k -> buildHttpClient(key, ocspCacheFile, key.getGzipDisabled()));
501+
CloseableHttpClient closeableHttpClient =
502+
httpClient.computeIfAbsent(
503+
key, k -> buildHttpClient(key, ocspCacheFile, key.getGzipDisabled()));
504+
if (detectClosedConnectionManager(closeableHttpClient)) {
505+
httpClient.remove(key);
506+
return httpClient.computeIfAbsent(
507+
key, k -> buildHttpClient(key, ocspCacheFile, key.getGzipDisabled()));
508+
}
509+
return closeableHttpClient;
510+
}
511+
512+
private static boolean detectClosedConnectionManager(CloseableHttpClient closeableHttpClient)
513+
throws RuntimeException {
514+
// There is no simple way to detect is the connection manager is closed...
515+
try {
516+
Field connManagerField = closeableHttpClient.getClass().getDeclaredField("connManager");
517+
connManagerField.setAccessible(true);
518+
PoolingHttpClientConnectionManager connectionManager =
519+
(PoolingHttpClientConnectionManager) connManagerField.get(closeableHttpClient);
520+
Field isShutdownField = connectionManager.getClass().getDeclaredField("isShutDown");
521+
isShutdownField.setAccessible(true);
522+
AtomicBoolean isShutdown = (AtomicBoolean) isShutdownField.get(connectionManager);
523+
return isShutdown.get();
524+
} catch (NoSuchFieldException | IllegalAccessException e) {
525+
throw new RuntimeException(e);
526+
}
502527
}
503528

504529
/**

src/test/java/net/snowflake/client/jdbc/ConnectionLatestIT.java

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1662,4 +1662,27 @@ public void testDisableOCSPChecksMode() throws SQLException {
16621662
assertThat(
16631663
thrown.getErrorCode(), anyOf(is(INVALID_CONNECTION_INFO_CODE), is(BAD_REQUEST_GS_CODE)));
16641664
}
1665+
1666+
/** Added after version 3.22.0 */
1667+
@Test
1668+
public void testRecoverFromClosedHttpConnectionManager() throws SQLException {
1669+
try (Connection connection = getConnection();
1670+
Statement statement = connection.createStatement()) {
1671+
HttpUtil.httpClient
1672+
.values()
1673+
.forEach(
1674+
closeableHttpClient -> {
1675+
try {
1676+
closeableHttpClient.close();
1677+
} catch (IOException e) {
1678+
throw new RuntimeException(e);
1679+
}
1680+
});
1681+
try (ResultSet resultSet = statement.executeQuery("Select 1")) {
1682+
assertTrue(resultSet.next());
1683+
assertEquals(1, resultSet.getInt(1));
1684+
assertFalse(resultSet.next());
1685+
}
1686+
}
1687+
}
16651688
}

0 commit comments

Comments
 (0)