Skip to content

Commit b02ee5e

Browse files
authored
Merge pull request ReactiveX#246 from szmg/fix-retrofit-enqueued-call
make async retrofit call not make the request when circuit is open
2 parents 35dd477 + 39c46ec commit b02ee5e

File tree

2 files changed

+40
-1
lines changed

2 files changed

+40
-1
lines changed

resilience4j-retrofit/src/main/java/io/github/resilience4j/retrofit/RetrofitCircuitBreaker.java

+1
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ public void enqueue(final Callback<T> callback) {
5858
CircuitBreakerUtils.isCallPermitted(circuitBreaker);
5959
} catch (CircuitBreakerOpenException cb) {
6060
callback.onFailure(call, cb);
61+
return;
6162
}
6263

6364
final StopWatch stopWatch = StopWatch.start(circuitBreaker.getName());

resilience4j-retrofit/src/test/java/io/github/resilience4j/retrofit/RetrofitCircuitBreakerTest.java

+39-1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
import com.github.tomakehurst.wiremock.junit.WireMockRule;
2222
import io.github.resilience4j.circuitbreaker.CircuitBreaker;
2323
import io.github.resilience4j.circuitbreaker.CircuitBreakerConfig;
24+
import io.github.resilience4j.circuitbreaker.CircuitBreakerOpenException;
25+
import okhttp3.Dispatcher;
2426
import okhttp3.OkHttpClient;
2527
import org.junit.Before;
2628
import org.junit.Rule;
@@ -34,6 +36,7 @@
3436

3537
import static com.github.tomakehurst.wiremock.client.WireMock.*;
3638
import static org.assertj.core.api.Assertions.assertThat;
39+
import static org.assertj.core.api.Assertions.fail;
3740

3841
/**
3942
* Tests the integration of the Retrofit HTTP client and {@link CircuitBreaker}
@@ -50,14 +53,16 @@ public class RetrofitCircuitBreakerTest {
5053

5154
private CircuitBreaker circuitBreaker = CircuitBreaker.of("test", circuitBreakerConfig);
5255

56+
private OkHttpClient client;
57+
5358
private RetrofitService service;
5459

5560
@Before
5661
public void setUp() {
5762
this.circuitBreaker = CircuitBreaker.of("test", circuitBreakerConfig);
5863

5964
final long TIMEOUT = 300; // ms
60-
final OkHttpClient client = new OkHttpClient.Builder()
65+
this.client = new OkHttpClient.Builder()
6166
.connectTimeout(TIMEOUT, TimeUnit.MILLISECONDS)
6267
.readTimeout(TIMEOUT, TimeUnit.MILLISECONDS)
6368
.writeTimeout(TIMEOUT, TimeUnit.MILLISECONDS)
@@ -212,6 +217,27 @@ public void decorateUnsuccessfulEnqueuedCall() throws Throwable {
212217
assertThat(metrics.getNumberOfFailedCalls()).isEqualTo(1);
213218
}
214219

220+
@Test
221+
public void shouldNotCallServiceOnEnqueueWhenOpen() throws Throwable {
222+
stubFor(get(urlPathEqualTo("/greeting"))
223+
.willReturn(aResponse()
224+
.withStatus(200)
225+
.withHeader("Content-Type", "text/plain")
226+
.withBody("hello world")));
227+
228+
circuitBreaker.transitionToOpenState();
229+
230+
try {
231+
EnqueueDecorator.enqueue(service.greeting());
232+
fail("CircuitBreakerOpenException was expected");
233+
} catch (CircuitBreakerOpenException ignore) {
234+
235+
}
236+
237+
ensureAllRequestsAreExecuted(Duration.ofSeconds(1));
238+
verify(0, getRequestedFor(urlPathEqualTo("/greeting")));
239+
}
240+
215241
@Test(expected = IllegalArgumentException.class)
216242
public void shouldThrowOnBadService() {
217243
BadRetrofitService badService = new Retrofit.Builder()
@@ -222,4 +248,16 @@ public void shouldThrowOnBadService() {
222248

223249
badService.greeting();
224250
}
251+
252+
private void ensureAllRequestsAreExecuted(Duration timeout) throws InterruptedException {
253+
long end = System.nanoTime() + timeout.toNanos();
254+
Dispatcher dispatcher = client.dispatcher();
255+
while (System.nanoTime() < end) {
256+
if (dispatcher.queuedCallsCount() <= 0 && dispatcher.runningCallsCount() <= 0) {
257+
return;
258+
}
259+
Thread.sleep(10);
260+
}
261+
fail("Timeout exceeded while waiting for requests to be finished");
262+
}
225263
}

0 commit comments

Comments
 (0)