Search in sources :

Example 1 with AbortExecutionException

use of com.netflix.loadbalancer.reactive.ExecutionListener.AbortExecutionException in project ribbon by Netflix.

the class ListenerTest method testAbortedExecution.

@Test
public void testAbortedExecution() {
    IClientConfig config = DefaultClientConfigImpl.getClientConfigWithDefaultValues().withProperty(CommonClientConfigKey.ConnectTimeout, "100").withProperty(CommonClientConfigKey.MaxAutoRetries, 1).withProperty(CommonClientConfigKey.MaxAutoRetriesNextServer, 1);
    HttpClientRequest<ByteBuf> request = HttpClientRequest.createGet("/testAsync/person");
    Server badServer = new Server("localhost:12345");
    Server badServer2 = new Server("localhost:34567");
    List<Server> servers = Lists.newArrayList(badServer, badServer2);
    BaseLoadBalancer lb = LoadBalancerBuilder.<Server>newBuilder().withRule(new AvailabilityFilteringRule()).withPing(new DummyPing()).buildFixedServerListLoadBalancer(servers);
    IClientConfig overrideConfig = DefaultClientConfigImpl.getEmptyConfig();
    TestExecutionListener listener = new TestExecutionListener(request, overrideConfig) {

        @Override
        public void onExecutionStart(ExecutionContext context) {
            throw new AbortExecutionException("exit now");
        }
    };
    List<ExecutionListener<HttpClientRequest<ByteBuf>, HttpClientResponse<ByteBuf>>> listeners = Lists.<ExecutionListener<HttpClientRequest<ByteBuf>, HttpClientResponse<ByteBuf>>>newArrayList(listener);
    LoadBalancingHttpClient<ByteBuf, ByteBuf> client = RibbonTransport.newHttpClient(lb, config, new NettyHttpLoadBalancerErrorHandler(config), listeners);
    final CountDownLatch latch = new CountDownLatch(1);
    final AtomicReference<Throwable> ref = new AtomicReference<Throwable>();
    client.submit(request, null, overrideConfig).subscribe(new Action1<HttpClientResponse<ByteBuf>>() {

        @Override
        public void call(HttpClientResponse<ByteBuf> byteBufHttpClientResponse) {
        }
    }, new Action1<Throwable>() {

        @Override
        public void call(Throwable throwable) {
            ref.set(throwable);
            latch.countDown();
        }
    });
    try {
        latch.await(500, TimeUnit.MILLISECONDS);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    assertTrue(ref.get() instanceof AbortExecutionException);
}
Also used : Server(com.netflix.loadbalancer.Server) MockWebServer(com.google.mockwebserver.MockWebServer) BaseLoadBalancer(com.netflix.loadbalancer.BaseLoadBalancer) AbortExecutionException(com.netflix.loadbalancer.reactive.ExecutionListener.AbortExecutionException) ByteBuf(io.netty.buffer.ByteBuf) ExecutionListener(com.netflix.loadbalancer.reactive.ExecutionListener) HttpClientResponse(io.reactivex.netty.protocol.http.client.HttpClientResponse) AtomicReference(java.util.concurrent.atomic.AtomicReference) CountDownLatch(java.util.concurrent.CountDownLatch) ExecutionContext(com.netflix.loadbalancer.reactive.ExecutionContext) DummyPing(com.netflix.loadbalancer.DummyPing) IClientConfig(com.netflix.client.config.IClientConfig) AvailabilityFilteringRule(com.netflix.loadbalancer.AvailabilityFilteringRule) Test(org.junit.Test)

Example 2 with AbortExecutionException

use of com.netflix.loadbalancer.reactive.ExecutionListener.AbortExecutionException in project ribbon by Netflix.

the class ListenerTest method testAbortedExecutionOnServer.

@Test
public void testAbortedExecutionOnServer() {
    IClientConfig config = DefaultClientConfigImpl.getClientConfigWithDefaultValues().withProperty(CommonClientConfigKey.ConnectTimeout, "100").withProperty(CommonClientConfigKey.MaxAutoRetries, 1).withProperty(CommonClientConfigKey.MaxAutoRetriesNextServer, 1);
    HttpClientRequest<ByteBuf> request = HttpClientRequest.createGet("/testAsync/person");
    Server badServer = new Server("localhost:12345");
    Server badServer2 = new Server("localhost:34567");
    List<Server> servers = Lists.newArrayList(badServer, badServer2);
    BaseLoadBalancer lb = LoadBalancerBuilder.<Server>newBuilder().withRule(new AvailabilityFilteringRule()).withPing(new DummyPing()).buildFixedServerListLoadBalancer(servers);
    IClientConfig overrideConfig = DefaultClientConfigImpl.getEmptyConfig();
    TestExecutionListener listener = new TestExecutionListener(request, overrideConfig) {

        @Override
        public void onStartWithServer(ExecutionContext context, ExecutionInfo info) {
            throw new AbortExecutionException("exit now");
        }
    };
    List<ExecutionListener<HttpClientRequest<ByteBuf>, HttpClientResponse<ByteBuf>>> listeners = Lists.<ExecutionListener<HttpClientRequest<ByteBuf>, HttpClientResponse<ByteBuf>>>newArrayList(listener);
    LoadBalancingHttpClient<ByteBuf, ByteBuf> client = RibbonTransport.newHttpClient(lb, config, new NettyHttpLoadBalancerErrorHandler(config), listeners);
    final CountDownLatch latch = new CountDownLatch(1);
    final AtomicReference<Throwable> ref = new AtomicReference<Throwable>();
    client.submit(request, null, overrideConfig).subscribe(new Action1<HttpClientResponse<ByteBuf>>() {

        @Override
        public void call(HttpClientResponse<ByteBuf> byteBufHttpClientResponse) {
        }
    }, new Action1<Throwable>() {

        @Override
        public void call(Throwable throwable) {
            ref.set(throwable);
            latch.countDown();
        }
    });
    try {
        latch.await(500, TimeUnit.MILLISECONDS);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    assertTrue(ref.get() instanceof AbortExecutionException);
}
Also used : Server(com.netflix.loadbalancer.Server) MockWebServer(com.google.mockwebserver.MockWebServer) ExecutionInfo(com.netflix.loadbalancer.reactive.ExecutionInfo) BaseLoadBalancer(com.netflix.loadbalancer.BaseLoadBalancer) AbortExecutionException(com.netflix.loadbalancer.reactive.ExecutionListener.AbortExecutionException) ByteBuf(io.netty.buffer.ByteBuf) ExecutionListener(com.netflix.loadbalancer.reactive.ExecutionListener) HttpClientResponse(io.reactivex.netty.protocol.http.client.HttpClientResponse) AtomicReference(java.util.concurrent.atomic.AtomicReference) CountDownLatch(java.util.concurrent.CountDownLatch) ExecutionContext(com.netflix.loadbalancer.reactive.ExecutionContext) DummyPing(com.netflix.loadbalancer.DummyPing) IClientConfig(com.netflix.client.config.IClientConfig) AvailabilityFilteringRule(com.netflix.loadbalancer.AvailabilityFilteringRule) Test(org.junit.Test)

Example 3 with AbortExecutionException

use of com.netflix.loadbalancer.reactive.ExecutionListener.AbortExecutionException in project ribbon by Netflix.

the class LoadBalancerCommand method submit.

/**
 * Create an {@link Observable} that once subscribed execute network call asynchronously with a server chosen by load balancer.
 * If there are any errors that are indicated as retriable by the {@link RetryHandler}, they will be consumed internally by the
 * function and will not be observed by the {@link Observer} subscribed to the returned {@link Observable}. If number of retries has
 * exceeds the maximal allowed, a final error will be emitted by the returned {@link Observable}. Otherwise, the first successful
 * result during execution and retries will be emitted.
 */
public Observable<T> submit(final ServerOperation<T> operation) {
    final ExecutionInfoContext context = new ExecutionInfoContext();
    if (listenerInvoker != null) {
        try {
            listenerInvoker.onExecutionStart();
        } catch (AbortExecutionException e) {
            return Observable.error(e);
        }
    }
    final int maxRetrysSame = retryHandler.getMaxRetriesOnSameServer();
    final int maxRetrysNext = retryHandler.getMaxRetriesOnNextServer();
    // Use the load balancer
    Observable<T> o = (server == null ? selectServer() : Observable.just(server)).concatMap(new Func1<Server, Observable<T>>() {

        @Override
        public // Called for each server being selected
        Observable<T> call(Server server) {
            context.setServer(server);
            final ServerStats stats = loadBalancerContext.getServerStats(server);
            // Called for each attempt and retry
            Observable<T> o = Observable.just(server).concatMap(new Func1<Server, Observable<T>>() {

                @Override
                public Observable<T> call(final Server server) {
                    context.incAttemptCount();
                    loadBalancerContext.noteOpenConnection(stats);
                    if (listenerInvoker != null) {
                        try {
                            listenerInvoker.onStartWithServer(context.toExecutionInfo());
                        } catch (AbortExecutionException e) {
                            return Observable.error(e);
                        }
                    }
                    final Stopwatch tracer = loadBalancerContext.getExecuteTracer().start();
                    return operation.call(server).doOnEach(new Observer<T>() {

                        private T entity;

                        @Override
                        public void onCompleted() {
                            recordStats(tracer, stats, entity, null);
                        // TODO: What to do if onNext or onError are never called?
                        }

                        @Override
                        public void onError(Throwable e) {
                            recordStats(tracer, stats, null, e);
                            logger.debug("Got error {} when executed on server {}", e, server);
                            if (listenerInvoker != null) {
                                listenerInvoker.onExceptionWithServer(e, context.toExecutionInfo());
                            }
                        }

                        @Override
                        public void onNext(T entity) {
                            this.entity = entity;
                            if (listenerInvoker != null) {
                                listenerInvoker.onExecutionSuccess(entity, context.toExecutionInfo());
                            }
                        }

                        private void recordStats(Stopwatch tracer, ServerStats stats, Object entity, Throwable exception) {
                            tracer.stop();
                            loadBalancerContext.noteRequestCompletion(stats, entity, exception, tracer.getDuration(TimeUnit.MILLISECONDS), retryHandler);
                        }
                    });
                }
            });
            if (maxRetrysSame > 0)
                o = o.retry(retryPolicy(maxRetrysSame, true));
            return o;
        }
    });
    if (maxRetrysNext > 0 && server == null)
        o = o.retry(retryPolicy(maxRetrysNext, false));
    return o.onErrorResumeNext(new Func1<Throwable, Observable<T>>() {

        @Override
        public Observable<T> call(Throwable e) {
            if (context.getAttemptCount() > 0) {
                if (maxRetrysNext > 0 && context.getServerAttemptCount() == (maxRetrysNext + 1)) {
                    e = new ClientException(ClientException.ErrorType.NUMBEROF_RETRIES_NEXTSERVER_EXCEEDED, "Number of retries on next server exceeded max " + maxRetrysNext + " retries, while making a call for: " + context.getServer(), e);
                } else if (maxRetrysSame > 0 && context.getAttemptCount() == (maxRetrysSame + 1)) {
                    e = new ClientException(ClientException.ErrorType.NUMBEROF_RETRIES_EXEEDED, "Number of retries exceeded max " + maxRetrysSame + " retries, while making a call for: " + context.getServer(), e);
                }
            }
            if (listenerInvoker != null) {
                listenerInvoker.onExecutionFailed(e, context.toFinalExecutionInfo());
            }
            return Observable.error(e);
        }
    });
}
Also used : Server(com.netflix.loadbalancer.Server) Stopwatch(com.netflix.servo.monitor.Stopwatch) AbortExecutionException(com.netflix.loadbalancer.reactive.ExecutionListener.AbortExecutionException) Observable(rx.Observable) ServerStats(com.netflix.loadbalancer.ServerStats) ClientException(com.netflix.client.ClientException) Func1(rx.functions.Func1)

Aggregations

Server (com.netflix.loadbalancer.Server)3 AbortExecutionException (com.netflix.loadbalancer.reactive.ExecutionListener.AbortExecutionException)3 MockWebServer (com.google.mockwebserver.MockWebServer)2 IClientConfig (com.netflix.client.config.IClientConfig)2 AvailabilityFilteringRule (com.netflix.loadbalancer.AvailabilityFilteringRule)2 BaseLoadBalancer (com.netflix.loadbalancer.BaseLoadBalancer)2 DummyPing (com.netflix.loadbalancer.DummyPing)2 ExecutionContext (com.netflix.loadbalancer.reactive.ExecutionContext)2 ExecutionListener (com.netflix.loadbalancer.reactive.ExecutionListener)2 ByteBuf (io.netty.buffer.ByteBuf)2 HttpClientResponse (io.reactivex.netty.protocol.http.client.HttpClientResponse)2 CountDownLatch (java.util.concurrent.CountDownLatch)2 AtomicReference (java.util.concurrent.atomic.AtomicReference)2 Test (org.junit.Test)2 ClientException (com.netflix.client.ClientException)1 ServerStats (com.netflix.loadbalancer.ServerStats)1 ExecutionInfo (com.netflix.loadbalancer.reactive.ExecutionInfo)1 Stopwatch (com.netflix.servo.monitor.Stopwatch)1 Observable (rx.Observable)1 Func1 (rx.functions.Func1)1