Search in sources :

Example 1 with DecoratedCall

use of io.github.resilience4j.retrofit.internal.DecoratedCall in project resilience4j by resilience4j.

the class RetrofitCircuitBreaker method decorateCall.

/**
 * Decorate {@link Call}s allow {@link CircuitBreaker} functionality.
 *
 * @param circuitBreaker  {@link CircuitBreaker} to apply
 * @param call            Call to decorate
 * @param responseSuccess determines whether the response should be considered an expected response
 * @param <T> Response type of call
 * @return Original Call decorated with CircuitBreaker
 */
static <T> Call<T> decorateCall(final CircuitBreaker circuitBreaker, final Call<T> call, final Predicate<Response> responseSuccess) {
    return new DecoratedCall<T>(call) {

        @Override
        public void enqueue(final Callback<T> callback) {
            try {
                CircuitBreakerUtils.isCallPermitted(circuitBreaker);
            } catch (CircuitBreakerOpenException cb) {
                callback.onFailure(call, cb);
            }
            final StopWatch stopWatch = StopWatch.start(circuitBreaker.getName());
            call.enqueue(new Callback<T>() {

                @Override
                public void onResponse(final Call<T> call, final Response<T> response) {
                    if (responseSuccess.test(response)) {
                        circuitBreaker.onSuccess(stopWatch.stop().getProcessingDuration().toNanos());
                    } else {
                        final Throwable throwable = new Throwable("Response error: HTTP " + response.code() + " - " + response.message());
                        circuitBreaker.onError(stopWatch.stop().getProcessingDuration().toNanos(), throwable);
                    }
                    callback.onResponse(call, response);
                }

                @Override
                public void onFailure(final Call<T> call, final Throwable t) {
                    circuitBreaker.onError(stopWatch.stop().getProcessingDuration().toNanos(), t);
                    callback.onFailure(call, t);
                }
            });
        }

        @Override
        public Response<T> execute() throws IOException {
            CircuitBreakerUtils.isCallPermitted(circuitBreaker);
            final StopWatch stopWatch = StopWatch.start(circuitBreaker.getName());
            try {
                final Response<T> response = call.execute();
                if (responseSuccess.test(response)) {
                    circuitBreaker.onSuccess(stopWatch.stop().getProcessingDuration().toNanos());
                } else {
                    final Throwable throwable = new Throwable("Response error: HTTP " + response.code() + " - " + response.message());
                    circuitBreaker.onError(stopWatch.stop().getProcessingDuration().toNanos(), throwable);
                }
                return response;
            } catch (Throwable throwable) {
                circuitBreaker.onError(stopWatch.stop().getProcessingDuration().toNanos(), throwable);
                throw throwable;
            }
        }
    };
}
Also used : DecoratedCall(io.github.resilience4j.retrofit.internal.DecoratedCall) Callback(retrofit2.Callback) CircuitBreakerOpenException(io.github.resilience4j.circuitbreaker.CircuitBreakerOpenException) StopWatch(io.github.resilience4j.core.StopWatch)

Aggregations

CircuitBreakerOpenException (io.github.resilience4j.circuitbreaker.CircuitBreakerOpenException)1 StopWatch (io.github.resilience4j.core.StopWatch)1 DecoratedCall (io.github.resilience4j.retrofit.internal.DecoratedCall)1 Callback (retrofit2.Callback)1