Source:
public void testLoadBalancingObservablesWithReadTimeout() throws Exception { NettyHttpLoadBalancerErrorHandler errorHandler = new NettyHttpLoadBalancerErrorHandler(1, 3, true); MockWebServer server = new MockWebServer(); String content = "{\"name\": \"ribbon\", \"age\": 2}"; server.enqueue(new MockResponse().setResponseCode(200).setHeader("Content-type", "application/json") .setBody(content)); server.play(); IClientConfig config = DefaultClientConfigImpl.getClientConfigWithDefaultValues() .set(CommonClientConfigKey.ReadTimeout, 100); HttpClientRequest<ByteBuf> request = HttpClientRequest.createGet("/testAsync/readTimeout"); BaseLoadBalancer lb = new BaseLoadBalancer(new DummyPing(), new AvailabilityFilteringRule()); NettyHttpClient<ByteBuf, ByteBuf> lbObservables = (NettyHttpClient<ByteBuf, ByteBuf>) RibbonTransport.newHttpClient(lb, config, errorHandler); Server goodServer = new Server("localhost:" + server.getPort()); Server badServer = new Server("localhost:" + port); List<Server> servers = Lists.newArrayList(goodServer, badServer, badServer, goodServer); lb.setServersList(servers); Observable<Person> observableWithRetries = getPersonObservable(lbObservables.submit(request)); ObserverWithLatch<Person> observer = new ObserverWithLatch<Person>(); observableWithRetries.subscribe(observer); observer.await(); assertEquals("ribbon", observer.obj.name); assertEquals(2, observer.obj.age); ServerStats stats = lbObservables.getServerStats(badServer); server.shutdown(); HttpClientListener listener = lbObservables.getListener(); Thread.sleep(1000); assertEquals(5, listener.getPoolReleases()); assertEquals(0, listener.getPoolReuse()); assertEquals(4, stats.getTotalRequestsCount()); assertEquals(0, stats.getActiveRequestsCount()); assertEquals(4, stats.getSuccessiveConnectionFailureCount()); stats = lbObservables.getServerStats(goodServer); assertEquals(1, stats.getTotalRequestsCount()); assertEquals(0, stats.getActiveRequestsCount()); assertEquals(0, stats.getSuccessiveConnectionFailureCount()); }

Target:
public void testLoadBalancingObservablesWithReadTimeout() throws Exception { NettyHttpLoadBalancerErrorHandler errorHandler = new NettyHttpLoadBalancerErrorHandler(1, 3, true); MockWebServer server = new MockWebServer(); String content = "{\"name\": \"ribbon\", \"age\": 2}"; server.enqueue(new MockResponse().setResponseCode(200).setHeader("Content-type", "application/json") .setBody(content)); server.play(); IClientConfig config = DefaultClientConfigImpl.getClientConfigWithDefaultValues() .set(CommonClientConfigKey.ReadTimeout, 100); HttpClientRequest<ByteBuf> request = HttpClientRequest.createGet("/testAsync/readTimeout"); BaseLoadBalancer lb = new BaseLoadBalancer(new DummyPing(), new AvailabilityFilteringRule()); NettyHttpClient<ByteBuf, ByteBuf> lbObservables = (NettyHttpClient<ByteBuf, ByteBuf>) RibbonTransport.newHttpClient(lb, config, errorHandler); Server goodServer = new Server("localhost:" + server.getPort()); Server badServer = new Server("localhost:" + port); List<Server> servers = Lists.newArrayList(goodServer, badServer, badServer, goodServer); lb.setServersList(servers); Observable<Person> observableWithRetries = getPersonObservable(lbObservables.submit(request)); ObserverWithLatch<Person> observer = new ObserverWithLatch<Person>(); observableWithRetries.subscribe(observer); observer.await(); assertEquals("ribbon", observer.obj.name); assertEquals(2, observer.obj.age); ServerStats stats = lbObservables.getServerStats(badServer); server.shutdown(); final HttpClientListener listener = lbObservables.getListener(); waitUntilTrueOrTimeout(1000, new Func0<Boolean>() { @Override public Boolean call() { return listener.getPoolReleases() == 5; } }); assertEquals(0, listener.getPoolReuse()); assertEquals(4, stats.getTotalRequestsCount()); assertEquals(0, stats.getActiveRequestsCount()); assertEquals(4, stats.getSuccessiveConnectionFailureCount()); stats = lbObservables.getServerStats(goodServer); assertEquals(1, stats.getTotalRequestsCount()); assertEquals(0, stats.getActiveRequestsCount()); assertEquals(0, stats.getSuccessiveConnectionFailureCount()); }