Search in sources :

Example 6 with Callback

use of com.linkedin.common.callback.Callback in project rest.li by linkedin.

the class TrackerClientTest method testCallTrackingRestRequest.

@Test
public void testCallTrackingRestRequest() throws Exception {
    URI uri = URI.create("http://test.qa.com:1234/foo");
    SettableClock clock = new SettableClock();
    AtomicInteger action = new AtomicInteger(0);
    TransportClient tc = new TransportClient() {

        @Override
        public void restRequest(RestRequest request, RequestContext requestContext, Map<String, String> wireAttrs, TransportCallback<RestResponse> callback) {
            clock.addDuration(5);
            switch(action.get()) {
                // success
                case 0:
                    callback.onResponse(TransportResponseImpl.success(RestResponse.NO_RESPONSE));
                    break;
                // fail with rest exception
                case 1:
                    callback.onResponse(TransportResponseImpl.error(RestException.forError(500, "rest exception")));
                    break;
                // fail with timeout exception
                case 2:
                    callback.onResponse(TransportResponseImpl.error(new RemoteInvocationException(new TimeoutException())));
                    break;
                // fail with other exception
                default:
                    callback.onResponse(TransportResponseImpl.error(new RuntimeException()));
                    break;
            }
        }

        @Override
        public void shutdown(Callback<None> callback) {
        }
    };
    TrackerClient client = createTrackerClient(tc, clock, uri);
    CallTracker callTracker = client.getCallTracker();
    CallTracker.CallStats stats;
    DegraderControl degraderControl = client.getDegraderControl(DefaultPartitionAccessor.DEFAULT_PARTITION_ID);
    client.restRequest(new RestRequestBuilder(uri).build(), new RequestContext(), new HashMap<>(), new TestTransportCallback<>());
    clock.addDuration(5000);
    stats = callTracker.getCallStats();
    Assert.assertEquals(stats.getCallCount(), 1);
    Assert.assertEquals(stats.getErrorCount(), 0);
    Assert.assertEquals(stats.getCallCountTotal(), 1);
    Assert.assertEquals(stats.getErrorCountTotal(), 0);
    Assert.assertEquals(degraderControl.getCurrentComputedDropRate(), 0.0, 0.001);
    action.set(1);
    client.restRequest(new RestRequestBuilder(uri).build(), new RequestContext(), new HashMap<>(), new TestTransportCallback<>());
    clock.addDuration(5000);
    stats = callTracker.getCallStats();
    Assert.assertEquals(stats.getCallCount(), 1);
    Assert.assertEquals(stats.getErrorCount(), 1);
    Assert.assertEquals(stats.getCallCountTotal(), 2);
    Assert.assertEquals(stats.getErrorCountTotal(), 1);
    Assert.assertEquals(degraderControl.getCurrentComputedDropRate(), 0.2, 0.001);
    action.set(2);
    client.restRequest(new RestRequestBuilder(uri).build(), new RequestContext(), new HashMap<>(), new TestTransportCallback<>());
    clock.addDuration(5000);
    stats = callTracker.getCallStats();
    Assert.assertEquals(stats.getCallCount(), 1);
    Assert.assertEquals(stats.getErrorCount(), 1);
    Assert.assertEquals(stats.getCallCountTotal(), 3);
    Assert.assertEquals(stats.getErrorCountTotal(), 2);
    Assert.assertEquals(degraderControl.getCurrentComputedDropRate(), 0.4, 0.001);
    action.set(3);
    client.restRequest(new RestRequestBuilder(uri).build(), new RequestContext(), new HashMap<>(), new TestTransportCallback<>());
    clock.addDuration(5000);
    stats = callTracker.getCallStats();
    Assert.assertEquals(stats.getCallCount(), 1);
    Assert.assertEquals(stats.getErrorCount(), 1);
    Assert.assertEquals(stats.getCallCountTotal(), 4);
    Assert.assertEquals(stats.getErrorCountTotal(), 3);
    Assert.assertEquals(degraderControl.getCurrentComputedDropRate(), 0.2, 0.001);
}
Also used : TransportCallback(com.linkedin.r2.transport.common.bridge.common.TransportCallback) TransportClient(com.linkedin.r2.transport.common.bridge.client.TransportClient) DegraderControl(com.linkedin.util.degrader.DegraderControl) URI(java.net.URI) RestRequest(com.linkedin.r2.message.rest.RestRequest) Callback(com.linkedin.common.callback.Callback) TransportCallback(com.linkedin.r2.transport.common.bridge.common.TransportCallback) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) SettableClock(com.linkedin.util.clock.SettableClock) RestRequestBuilder(com.linkedin.r2.message.rest.RestRequestBuilder) RequestContext(com.linkedin.r2.message.RequestContext) RemoteInvocationException(com.linkedin.r2.RemoteInvocationException) HashMap(java.util.HashMap) Map(java.util.Map) TimeoutException(java.util.concurrent.TimeoutException) CallTracker(com.linkedin.util.degrader.CallTracker) Test(org.testng.annotations.Test)

Example 7 with Callback

use of com.linkedin.common.callback.Callback in project rest.li by linkedin.

the class TrackerClientTest method testCallTrackingStreamRequest.

@Test
public void testCallTrackingStreamRequest() throws Exception {
    URI uri = URI.create("http://test.qa.com:1234/foo");
    SettableClock clock = new SettableClock();
    AtomicInteger action = new AtomicInteger(0);
    TransportClient tc = new TransportClient() {

        @Override
        public void restRequest(RestRequest request, RequestContext requestContext, Map<String, String> wireAttrs, TransportCallback<RestResponse> callback) {
        }

        @Override
        public void streamRequest(StreamRequest request, RequestContext requestContext, Map<String, String> wireAttrs, TransportCallback<StreamResponse> callback) {
            clock.addDuration(5);
            switch(action.get()) {
                // success
                case 0:
                    callback.onResponse(TransportResponseImpl.success(new StreamResponseBuilder().build(EntityStreams.emptyStream())));
                    break;
                // fail with stream exception
                case 1:
                    callback.onResponse(TransportResponseImpl.error(new StreamException(new StreamResponseBuilder().setStatus(500).build(EntityStreams.emptyStream()))));
                    break;
                // fail with timeout exception
                case 2:
                    callback.onResponse(TransportResponseImpl.error(new RemoteInvocationException(new TimeoutException())));
                    break;
                // fail with other exception
                default:
                    callback.onResponse(TransportResponseImpl.error(new RuntimeException()));
                    break;
            }
        }

        @Override
        public void shutdown(Callback<None> callback) {
        }
    };
    TrackerClient client = createTrackerClient(tc, clock, uri);
    CallTracker callTracker = client.getCallTracker();
    CallTracker.CallStats stats;
    DegraderControl degraderControl = client.getDegraderControl(DefaultPartitionAccessor.DEFAULT_PARTITION_ID);
    DelayConsumeCallback delayConsumeCallback = new DelayConsumeCallback();
    client.streamRequest(new StreamRequestBuilder(uri).build(EntityStreams.emptyStream()), new RequestContext(), new HashMap<>(), delayConsumeCallback);
    clock.addDuration(5);
    // we only recorded the time when stream response arrives, but callcompletion.endcall hasn't been called yet.
    Assert.assertEquals(callTracker.getCurrentCallCountTotal(), 0);
    Assert.assertEquals(callTracker.getCurrentErrorCountTotal(), 0);
    // delay
    clock.addDuration(100);
    delayConsumeCallback.consume();
    clock.addDuration(5000);
    // now that we consumed the entity stream, callcompletion.endcall has been called.
    stats = callTracker.getCallStats();
    Assert.assertEquals(stats.getCallCount(), 1);
    Assert.assertEquals(stats.getErrorCount(), 0);
    Assert.assertEquals(stats.getCallCountTotal(), 1);
    Assert.assertEquals(stats.getErrorCountTotal(), 0);
    Assert.assertEquals(degraderControl.getCurrentComputedDropRate(), 0.0, 0.001);
    action.set(1);
    client.streamRequest(new StreamRequestBuilder(uri).build(EntityStreams.emptyStream()), new RequestContext(), new HashMap<>(), delayConsumeCallback);
    clock.addDuration(5);
    // we endcall with error immediately for stream exception, even before the entity is consumed
    Assert.assertEquals(callTracker.getCurrentCallCountTotal(), 2);
    Assert.assertEquals(callTracker.getCurrentErrorCountTotal(), 1);
    delayConsumeCallback.consume();
    clock.addDuration(5000);
    // no change in tracking after entity is consumed
    stats = callTracker.getCallStats();
    Assert.assertEquals(stats.getCallCount(), 1);
    Assert.assertEquals(stats.getErrorCount(), 1);
    Assert.assertEquals(stats.getCallCountTotal(), 2);
    Assert.assertEquals(stats.getErrorCountTotal(), 1);
    Assert.assertEquals(degraderControl.getCurrentComputedDropRate(), 0.2, 0.001);
    action.set(2);
    client.streamRequest(new StreamRequestBuilder(uri).build(EntityStreams.emptyStream()), new RequestContext(), new HashMap<>(), new TestTransportCallback<>());
    clock.addDuration(5);
    Assert.assertEquals(callTracker.getCurrentCallCountTotal(), 3);
    Assert.assertEquals(callTracker.getCurrentErrorCountTotal(), 2);
    clock.addDuration(5000);
    stats = callTracker.getCallStats();
    Assert.assertEquals(stats.getCallCount(), 1);
    Assert.assertEquals(stats.getErrorCount(), 1);
    Assert.assertEquals(stats.getCallCountTotal(), 3);
    Assert.assertEquals(stats.getErrorCountTotal(), 2);
    Assert.assertEquals(degraderControl.getCurrentComputedDropRate(), 0.4, 0.001);
    action.set(3);
    client.streamRequest(new StreamRequestBuilder(uri).build(EntityStreams.emptyStream()), new RequestContext(), new HashMap<>(), new TestTransportCallback<>());
    clock.addDuration(5);
    Assert.assertEquals(callTracker.getCurrentCallCountTotal(), 4);
    Assert.assertEquals(callTracker.getCurrentErrorCountTotal(), 3);
    clock.addDuration(5000);
    stats = callTracker.getCallStats();
    Assert.assertEquals(stats.getCallCount(), 1);
    Assert.assertEquals(stats.getErrorCount(), 1);
    Assert.assertEquals(stats.getCallCountTotal(), 4);
    Assert.assertEquals(stats.getErrorCountTotal(), 3);
    Assert.assertEquals(degraderControl.getCurrentComputedDropRate(), 0.2, 0.001);
}
Also used : TransportCallback(com.linkedin.r2.transport.common.bridge.common.TransportCallback) TransportClient(com.linkedin.r2.transport.common.bridge.client.TransportClient) StreamResponseBuilder(com.linkedin.r2.message.stream.StreamResponseBuilder) DegraderControl(com.linkedin.util.degrader.DegraderControl) URI(java.net.URI) StreamRequestBuilder(com.linkedin.r2.message.stream.StreamRequestBuilder) StreamRequest(com.linkedin.r2.message.stream.StreamRequest) StreamException(com.linkedin.r2.message.stream.StreamException) RestRequest(com.linkedin.r2.message.rest.RestRequest) Callback(com.linkedin.common.callback.Callback) TransportCallback(com.linkedin.r2.transport.common.bridge.common.TransportCallback) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) SettableClock(com.linkedin.util.clock.SettableClock) RequestContext(com.linkedin.r2.message.RequestContext) RemoteInvocationException(com.linkedin.r2.RemoteInvocationException) HashMap(java.util.HashMap) Map(java.util.Map) TimeoutException(java.util.concurrent.TimeoutException) CallTracker(com.linkedin.util.degrader.CallTracker) Test(org.testng.annotations.Test)

Example 8 with Callback

use of com.linkedin.common.callback.Callback in project rest.li by linkedin.

the class ZKFSLoadBalancer method start.

@Override
public void start(final Callback<None> callback) {
    LOG.info("Starting ZKFSLoadBalancer");
    LOG.info("ZK connect string: {}", _connectString);
    LOG.info("ZK session timeout: {}ms", _sessionTimeout);
    LOG.info("ZK initial connect timeout: {}ms", _initialZKTimeout);
    if (_connectString == null || _connectString.isEmpty()) {
        callback.onError(new IllegalArgumentException("ZooKeeper connection string is null or empty"));
        return;
    }
    if (_zkFlagFile == null) {
        LOG.info("ZK flag file not specified");
    } else {
        LOG.info("ZK flag file: {}", _zkFlagFile.getAbsolutePath());
        LOG.info("ZK currently suppressed by flag file: {}", suppressZK());
    }
    _zkConnection = new ZKConnection(_connectString, _sessionTimeout, _shutdownAsynchronously, _isSymlinkAware);
    final TogglingLoadBalancer balancer = _loadBalancerFactory.createLoadBalancer(_zkConnection, _executor);
    // all other cases, we service requests from the old LoadBalancer until the new one is started
    if (_currentLoadBalancer == null) {
        _currentLoadBalancer = balancer;
    }
    Callback<None> wrapped = new Callback<None>() {

        @Override
        public void onSuccess(None none) {
            _currentLoadBalancer = balancer;
            callback.onSuccess(none);
        }

        @Override
        public void onError(Throwable e) {
            callback.onError(e);
        }
    };
    if (!_startupCallback.compareAndSet(null, wrapped)) {
        throw new IllegalStateException("Startup already in progress");
    }
    _executor.execute(new PropertyEventThread.PropertyEvent("startup") {

        @Override
        public void innerRun() {
            _zkConnection.addStateListener(new ZKListener(balancer));
            try {
                _zkConnection.start();
            } catch (Exception e) {
                LOG.error("Failed to start ZooKeeper (bad configuration?), enabling backup stores", e);
                Callback<None> startupCallback = _startupCallback.getAndSet(null);
                // TODO this should never be null
                balancer.enableBackup(startupCallback);
                return;
            }
            LOG.info("Started ZooKeeper");
            _executor.schedule(new Runnable() {

                @Override
                public void run() {
                    Callback<None> startupCallback = _startupCallback.getAndSet(null);
                    if (startupCallback != null) {
                        // Noone has enabled the stores yet either way
                        LOG.error("No response from ZooKeeper within {}ms, enabling backup stores", _initialZKTimeout);
                        balancer.enableBackup(startupCallback);
                    }
                }
            }, _initialZKTimeout, TimeUnit.MILLISECONDS);
        }
    });
}
Also used : ZKConnection(com.linkedin.d2.discovery.stores.zk.ZKConnection) TogglingLoadBalancer(com.linkedin.d2.balancer.util.TogglingLoadBalancer) KeeperException(org.apache.zookeeper.KeeperException) ServiceUnavailableException(com.linkedin.d2.balancer.ServiceUnavailableException) Callback(com.linkedin.common.callback.Callback) None(com.linkedin.common.util.None) PropertyEventThread(com.linkedin.d2.discovery.event.PropertyEventThread)

Example 9 with Callback

use of com.linkedin.common.callback.Callback in project rest.li by linkedin.

the class TestMIMEChainingMultipleSources method generateSuccessChainCallback.

private Callback<StreamResponse> generateSuccessChainCallback(final ClientMultiPartReceiver receiver) {
    return new Callback<StreamResponse>() {

        @Override
        public void onError(Throwable e) {
            Assert.fail();
        }

        @Override
        public void onSuccess(StreamResponse result) {
            final MultiPartMIMEReader reader = MultiPartMIMEReader.createAndAcquireStream(result);
            reader.registerReaderCallback(receiver);
        }
    };
}
Also used : FutureCallback(com.linkedin.common.callback.FutureCallback) Callback(com.linkedin.common.callback.Callback) MultiPartMIMEReaderCallback(com.linkedin.multipart.MultiPartMIMEReaderCallback) StreamResponse(com.linkedin.r2.message.stream.StreamResponse) MultiPartMIMEReader(com.linkedin.multipart.MultiPartMIMEReader)

Example 10 with Callback

use of com.linkedin.common.callback.Callback in project rest.li by linkedin.

the class TestMIMEChainingMultipleSources method generateServerAResponseCallback.

private Callback<StreamResponse> generateServerAResponseCallback(final StreamRequest incomingRequest, final Callback<StreamResponse> incomingRequestCallback) {
    return new Callback<StreamResponse>() {

        @Override
        public void onError(Throwable e) {
            Assert.fail();
        }

        @Override
        public void onSuccess(StreamResponse result) {
            final MultiPartMIMEReader reader = MultiPartMIMEReader.createAndAcquireStream(result);
            _serverAMultiPartCallback = new ServerAMultiPartCallback(incomingRequest, incomingRequestCallback);
            reader.registerReaderCallback(_serverAMultiPartCallback);
        }
    };
}
Also used : FutureCallback(com.linkedin.common.callback.FutureCallback) Callback(com.linkedin.common.callback.Callback) MultiPartMIMEReaderCallback(com.linkedin.multipart.MultiPartMIMEReaderCallback) StreamResponse(com.linkedin.r2.message.stream.StreamResponse) MultiPartMIMEReader(com.linkedin.multipart.MultiPartMIMEReader)

Aggregations

Callback (com.linkedin.common.callback.Callback)95 Test (org.testng.annotations.Test)64 AfterTest (org.testng.annotations.AfterTest)43 BeforeTest (org.testng.annotations.BeforeTest)43 RequestContext (com.linkedin.r2.message.RequestContext)37 RestResponse (com.linkedin.r2.message.rest.RestResponse)34 ByteString (com.linkedin.data.ByteString)29 RestRequest (com.linkedin.r2.message.rest.RestRequest)28 StreamResponse (com.linkedin.r2.message.stream.StreamResponse)28 AsyncStatusCollectionResource (com.linkedin.restli.server.twitter.AsyncStatusCollectionResource)28 URI (java.net.URI)28 RestLiCallback (com.linkedin.restli.internal.server.RestLiCallback)26 FilterChainCallback (com.linkedin.restli.internal.server.filter.FilterChainCallback)26 ResourceMethodDescriptor (com.linkedin.restli.internal.server.model.ResourceMethodDescriptor)26 ResourceModel (com.linkedin.restli.internal.server.model.ResourceModel)26 RequestExecutionCallback (com.linkedin.restli.server.RequestExecutionCallback)26 RestLiTestHelper.buildResourceModel (com.linkedin.restli.server.test.RestLiTestHelper.buildResourceModel)26 EasyMock.anyObject (org.easymock.EasyMock.anyObject)26 StreamRequest (com.linkedin.r2.message.stream.StreamRequest)25 RestRequestBuilder (com.linkedin.r2.message.rest.RestRequestBuilder)22