What is the difference between "ConnectionConfig.custom().setSocketTimeout(Timeout)" and "SocketConfig.custom().setSoTimeout(Timeout)"

285 views Asked by At

I have created an instance of PoolingHttpClientConnectionManager and set a socket timeout of 5 seconds in the ConnectionConfig. In this case, when accessing a backend service with a response time of 10 seconds for the first time, a SocketTimeoutException was correctly thrown. But in the second request, when reusing an already established connection, the client waited for 10 seconds and completed the request. Instead, if I set a 5-second SoTimeout in SocketConfig and run the test again. The setting works.

That's why I want to know the difference between each other. Is that an issue? The version is 5.3-alpha1.

The code:

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;


@RestController
public class TestController {

    @GetMapping("/ten")
    public String tenSecond() throws InterruptedException {
        Thread.sleep(10000);
        return "OK";
    }

    @GetMapping("")
    public String success()  {
        return "OK";
    }
}
import static org.assertj.core.api.Assertions.assertThat;

import java.net.SocketTimeoutException;
import org.apache.hc.client5.http.classic.methods.HttpGet;
import org.apache.hc.client5.http.config.ConnectionConfig;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.HttpClients;
import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager;
import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManagerBuilder;
import org.apache.hc.core5.http.io.SocketConfig;
import org.apache.hc.core5.http.io.entity.EntityUtils;
import org.apache.hc.core5.pool.PoolConcurrencyPolicy;
import org.apache.hc.core5.pool.PoolReusePolicy;
import org.apache.hc.core5.util.Timeout;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;


@SpringBootTest(
    webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT,
    properties = {"server.port=38080"})
class TestControllerTest {

  @Test
  // passed
  void socketWithoutSO() throws Exception {
    PoolingHttpClientConnectionManager connectionManager =
        PoolingHttpClientConnectionManagerBuilder.create()
            .setPoolConcurrencyPolicy(PoolConcurrencyPolicy.STRICT)
            .setConnPoolPolicy(PoolReusePolicy.LIFO)
            .build();

    connectionManager.setDefaultConnectionConfig(
        ConnectionConfig.custom().setSocketTimeout(Timeout.ofSeconds(5)).build());

    CloseableHttpClient httpClient =
        HttpClients.custom().setConnectionManager(connectionManager).build();

    SocketTimeoutException exception =
        Assertions.assertThrows(
            SocketTimeoutException.class,
            () ->
                httpClient.execute(
                    new HttpGet("http://127.0.0.1:38080/ten"),
                    response -> EntityUtils.toString(response.getEntity())));
    assertThat(exception).isInstanceOf(SocketTimeoutException.class);
  }

  @Test
  // failed
  void socketWithoutSOReuseConnection() throws Exception {
    PoolingHttpClientConnectionManager connectionManager =
        PoolingHttpClientConnectionManagerBuilder.create()
            .setPoolConcurrencyPolicy(PoolConcurrencyPolicy.STRICT)
            .setConnPoolPolicy(PoolReusePolicy.LIFO)
            .build();

    connectionManager.setDefaultConnectionConfig(
        ConnectionConfig.custom().setSocketTimeout(Timeout.ofSeconds(5)).build());

    CloseableHttpClient httpClient =
        HttpClients.custom().setConnectionManager(connectionManager).build();

    httpClient.execute(
        new HttpGet("http://127.0.0.1:38080"),
        response -> EntityUtils.toString(response.getEntity()));

    SocketTimeoutException exception =
        Assertions.assertThrows(
            SocketTimeoutException.class,
            () ->
                httpClient.execute(
                    new HttpGet("http://127.0.0.1:38080/ten"),
                    response -> EntityUtils.toString(response.getEntity())));
    assertThat(exception).isInstanceOf(SocketTimeoutException.class);
  }

  @Test
  // passed
  void socketWithSO() throws Exception {
    PoolingHttpClientConnectionManager connectionManager =
        PoolingHttpClientConnectionManagerBuilder.create()
            .setPoolConcurrencyPolicy(PoolConcurrencyPolicy.STRICT)
            .setConnPoolPolicy(PoolReusePolicy.LIFO)
            .build();

    connectionManager.setDefaultSocketConfig(
        SocketConfig.custom().setSoTimeout(Timeout.ofSeconds(5)).build());

    connectionManager.setDefaultConnectionConfig(
        ConnectionConfig.custom().setSocketTimeout(Timeout.ofSeconds(5)).build());

    CloseableHttpClient httpClient =
        HttpClients.custom().setConnectionManager(connectionManager).build();

    httpClient.execute(
        new HttpGet("http://127.0.0.1:38080"),
        response -> EntityUtils.toString(response.getEntity()));

    SocketTimeoutException exception =
        Assertions.assertThrows(
            SocketTimeoutException.class,
            () ->
                httpClient.execute(
                    new HttpGet("http://127.0.0.1:38080/ten"),
                    response -> EntityUtils.toString(response.getEntity())));
    assertThat(exception).isInstanceOf(SocketTimeoutException.class);
  }
}
0

There are 0 answers