Issue with Socket Timeout Exception when using shared PoolingHttpClientConnectionManager

49 Views Asked by At

I am facing an issue while using PoolingHttpClientConnectionManager in my Java application. I have a scenario where I need to handle socket timeout exceptions for some endpoints that might not respond in time. However, I'm observing unexpected behavior when using a shared connection manager versus creating a new connection manager each time.

Here's my code snippet:

'''

private static PoolingHttpClientConnectionManager connectionManager = null;

static {
    connectionManager = getPoolingHttpClientConnectionManager();
}

public static PoolingHttpClientConnectionManager getPoolingHttpClientConnectionManager() {
    PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager();
    connectionManager.setDefaultConnectionConfig(getConnectionConfig());
    return connectionManager;
}

public static CloseableHttpClient getHttpClientObject(Credential credentials, String url) {
    BasicCredentialsProvider credentialsProvider = getCredentialProvider(credentials, url);
    Registry<AuthSchemeFactory> authSchemeRegistry = getAuthSchemeRegistry();
    RequestConfig requestConfig = getRequestConfig();
    /*
     * PoolingHttpClientConnectionManager connectionManager =
     * getPoolingHttpClientConnectionManager();
     */
    HttpClientBuilder httpClientBuilder = HttpClients.custom()
            .setConnectionManager(connectionManager) // Using shared connection manager
            .setDefaultAuthSchemeRegistry(authSchemeRegistry)
            .setConnectionManagerShared(true) // Setting connection manager as shared
            .setDefaultRequestConfig(requestConfig);

    if (null != credentialsProvider) {
        httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
    }

    CloseableHttpClient httpClient = httpClientBuilder.build();

    return httpClient;
}

public static ConnectionConfig getConnectionConfig() {

    ConnectionConfig connectionConfig = null;

    connectionConfig = ConnectionConfig.custom()
            .setConnectTimeout(Timeout.of(4000, TimeUnit.MILLISECONDS))
            .setSocketTimeout(Timeout.of(1000, TimeUnit.MILLISECONDS))
            .build();
    return connectionConfig;
}

'''

When I use the shared connection manager, I don't get the expected socket timeout exception for endpoints that don't respond. However, if I uncomment the line to create a new connection manager each time, I do get the socket timeout exception as expected.

Could someone help me understand why this behavior is happening? What might be going wrong when I use a shared connection manager? Is there a way to make the shared connection manager work as expected with socket timeout exceptions?

Thank you in advance for any insights or suggestions!

0

There are 0 best solutions below