On Thu, 2017-03-02 at 12:23 +0000, Michael Orr wrote:
> Hi,
>
> I'm trying to create a unit test to show that the code we've written
> around HC is passing in connection pool parameters correctly. I want
> it to try to get an entry from the connection pool when the pool is
> already maxed out, and to prove that it will return with a failure
> within the time that I sent via setConnectionRequestTimeout.
>
> I set the 'MaxConnTotal' and 'MaxConnPerRoute' both to 1 on the
> HttpAsyncClient, then executed two HttpGet methods - the first
> HttpGet
> would be to a server URL that would take 10000ms to return, thus
> using
> up all connections in the pool for 10 seconds. By using
> 'setConnectionRequestTimeout(100)' in the RequestConfig I would
> expect
> that the second HttpGet would throw a TimeoutException after 100ms.
> What happens in practice, though, is that it waits the full 10000ms
> before throwing the TimeoutException.
>
> Is this behaviour by design?
Yes, it is (sort of). By default the non-blocking connection validates
pending connection requests only when leasing or releasing connections.
If I/O dispatch threads are inactive, like in your example, the
connection manager does not proactively scans request queue and evicts
expired requests.
One can force this behavior by using a dedicated monitor thread that
calls this method at regular intervals (say, every second)
PoolingNHttpClientConnectionManager#validatePendingRequests
This strategy has its cost, though, as it will increase pool lock
contention under load.
Hope this helps
Oleg
> And, if so, how do I force the second
> HttpGet to throw the error after 100ms?
>
> I'm using the following versions:
> * httpclient-4.5.3
> * httpasyncclient-4.1.3
> * httpcore-4.4.6
> * httpcore-nio-4.4.6
>
> The code I'm using is:
>
> -------- START CODE --------
>
> CloseableHttpAsyncClient client =
> HttpAsyncClients.custom().setMaxConnPerRoute(1)
> .setMaxConnTotal(1).build();
> client.start();
>
> RequestConfig requestConfig = RequestConfig.custom()
> .setConnectionRequestTimeout(100).build();
>
> // Request should take ~10000ms
> HttpGet method1 = new HttpGet("http://localhost:" +
> SLOW_SERVER_PORT + "/stuff");
> method1.setConfig(requestConfig);
>
> // Request should take ~10ms
> HttpGet method2 = new HttpGet("http://localhost:" +
> FAST_SERVER_PORT + "/stuff");
> method2.setConfig(requestConfig);
>
> long lStartTimeMillis = System.currentTimeMillis();
>
> Future<HttpResponse> promise1 = client.execute(method1,
> null);
> Future<HttpResponse> promise2 = client.execute(method2,
> null);
>
> try
> {
> promise2.get();
> fail();
> }
> catch (Exception e)
> {
> // Expected
> long lElapsedTimeMillis = System.currentTimeMillis() -
> lStartTimeMillis;
> assertTrue("Took too long to fail", lElapsedTimeMillis <
> 500);
> }
>
> -------- END CODE --------
>
> Thanks in advance,
>
> Michael
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [email protected]
> For additional commands, e-mail: [email protected]
>
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]