Search in sources :

Example 36 with Timeout

use of com.linkedin.r2.util.Timeout in project rest.li by linkedin.

the class AbstractAsyncR2Servlet method service.

@Override
public void service(final HttpServletRequest req, final HttpServletResponse resp) throws ServletException, IOException {
    RequestContext requestContext = ServletHelper.readRequestContext(req);
    RestRequest restRequest;
    try {
        restRequest = readFromServletRequest(req);
    } catch (URISyntaxException e) {
        writeToServletError(resp, RestStatus.BAD_REQUEST, e.toString());
        return;
    }
    final AsyncContext ctx = req.startAsync(req, resp);
    ctx.setTimeout(_timeout);
    ctx.addListener(new AsyncListener() {

        @Override
        public void onTimeout(AsyncEvent event) throws IOException {
            AsyncContext ctx = event.getAsyncContext();
            writeToServletError((HttpServletResponse) ctx.getResponse(), RestStatus.INTERNAL_SERVER_ERROR, "Server Timeout");
            ctx.complete();
        }

        @Override
        public void onStartAsync(AsyncEvent event) throws IOException {
        // Nothing to do here
        }

        @Override
        public void onError(AsyncEvent event) throws IOException {
            writeToServletError((HttpServletResponse) event.getSuppliedResponse(), RestStatus.INTERNAL_SERVER_ERROR, "Server Error");
            ctx.complete();
        }

        @Override
        public void onComplete(AsyncEvent event) throws IOException {
            Object exception = req.getAttribute(TRANSPORT_CALLBACK_IOEXCEPTION);
            if (exception != null)
                throw new IOException((IOException) exception);
        }
    });
    TransportCallback<RestResponse> callback = new TransportCallback<RestResponse>() {

        @Override
        public void onResponse(final TransportResponse<RestResponse> response) {
            // TransportCallback is usually invoked by non-servlet threads; hence we cannot assume that it's ok to
            // do blocking IO there. As a result, we should use AsyncContext.start() to do blocking IO using the
            // container/servlet threads. This still maintains the advantage of Async, meaning servlet thread is not
            // blocking-wait when the response is not ready.
            ctx.start(new Runnable() {

                @Override
                public void run() {
                    try {
                        writeToServletResponse(response, (HttpServletResponse) ctx.getResponse());
                    } catch (IOException e) {
                        req.setAttribute(TRANSPORT_CALLBACK_IOEXCEPTION, e);
                    } finally {
                        ctx.complete();
                    }
                }
            });
        }
    };
    getDispatcher().handleRequest(restRequest, requestContext, callback);
}
Also used : TransportCallback(com.linkedin.r2.transport.common.bridge.common.TransportCallback) RestResponse(com.linkedin.r2.message.rest.RestResponse) HttpServletResponse(javax.servlet.http.HttpServletResponse) AsyncContext(javax.servlet.AsyncContext) URISyntaxException(java.net.URISyntaxException) IOException(java.io.IOException) AsyncEvent(javax.servlet.AsyncEvent) TransportResponse(com.linkedin.r2.transport.common.bridge.common.TransportResponse) RestRequest(com.linkedin.r2.message.rest.RestRequest) AsyncListener(javax.servlet.AsyncListener) RequestContext(com.linkedin.r2.message.RequestContext)

Example 37 with Timeout

use of com.linkedin.r2.util.Timeout in project rest.li by linkedin.

the class AbstractR2Servlet method service.

@Override
protected void service(final HttpServletRequest req, final HttpServletResponse resp) throws ServletException, IOException {
    RequestContext requestContext = ServletHelper.readRequestContext(req);
    RestRequest restRequest;
    try {
        restRequest = readFromServletRequest(req);
    } catch (URISyntaxException e) {
        writeToServletError(resp, RestStatus.BAD_REQUEST, e.toString());
        return;
    }
    final AtomicReference<TransportResponse<RestResponse>> result = new AtomicReference<>();
    final CountDownLatch latch = new CountDownLatch(1);
    TransportCallback<RestResponse> callback = new TransportCallback<RestResponse>() {

        @Override
        public void onResponse(TransportResponse<RestResponse> response) {
            result.set(response);
            latch.countDown();
        }
    };
    getDispatcher().handleRequest(restRequest, requestContext, callback);
    try {
        if (latch.await(_timeout, TimeUnit.MILLISECONDS)) {
            writeToServletResponse(result.get(), resp);
        } else {
            writeToServletError(resp, RestStatus.INTERNAL_SERVER_ERROR, "Server Timeout after " + _timeout + "ms.");
        }
    } catch (InterruptedException e) {
        throw new ServletException("Interrupted!", e);
    }
}
Also used : ServletException(javax.servlet.ServletException) TransportCallback(com.linkedin.r2.transport.common.bridge.common.TransportCallback) RestRequest(com.linkedin.r2.message.rest.RestRequest) RestResponse(com.linkedin.r2.message.rest.RestResponse) AtomicReference(java.util.concurrent.atomic.AtomicReference) RequestContext(com.linkedin.r2.message.RequestContext) URISyntaxException(java.net.URISyntaxException) CountDownLatch(java.util.concurrent.CountDownLatch) TransportResponse(com.linkedin.r2.transport.common.bridge.common.TransportResponse)

Example 38 with Timeout

use of com.linkedin.r2.util.Timeout in project rest.li by linkedin.

the class TestConstantQpsRateLimiter method submitOnceGetMany.

@Test(timeOut = TEST_TIMEOUT)
public void submitOnceGetMany() {
    ClockedExecutor executor = new ClockedExecutor();
    ClockedExecutor circularBufferExecutor = new ClockedExecutor();
    ConstantQpsRateLimiter rateLimiter = new ConstantQpsRateLimiter(executor, executor, executor, TestEvictingCircularBuffer.getBuffer(circularBufferExecutor));
    rateLimiter.setRate(TEST_QPS, ONE_SECOND, UNLIMITED_BURST);
    rateLimiter.setBufferCapacity(1);
    TattlingCallback<None> tattler = new TattlingCallback<>(executor);
    rateLimiter.submit(tattler);
    executor.runFor(ONE_SECOND * TEST_NUM_CYCLES);
    Assert.assertTrue(tattler.getInteractCount() > 1);
}
Also used : ConstantQpsRateLimiter(com.linkedin.r2.transport.http.client.ConstantQpsRateLimiter) ClockedExecutor(com.linkedin.test.util.ClockedExecutor) None(com.linkedin.common.util.None) Test(org.testng.annotations.Test)

Example 39 with Timeout

use of com.linkedin.r2.util.Timeout in project rest.li by linkedin.

the class TestConstantQpsRateLimiter method eventLoopStopsWhenTtlExpiresAllRequests.

@Test(timeOut = TEST_TIMEOUT)
public void eventLoopStopsWhenTtlExpiresAllRequests() {
    ClockedExecutor executor = new ClockedExecutor();
    ConstantQpsRateLimiter rateLimiter = new ConstantQpsRateLimiter(executor, executor, executor, TestEvictingCircularBuffer.getBuffer(executor));
    rateLimiter.setRate(TEST_QPS, ONE_SECOND, UNLIMITED_BURST);
    rateLimiter.setBufferTtl(ONE_SECOND - 1, ChronoUnit.MILLIS);
    TattlingCallback<None> tattler = new TattlingCallback<>(executor);
    rateLimiter.submit(tattler);
    executor.runFor(ONE_SECOND * TEST_NUM_CYCLES);
    Assert.assertSame(tattler.getInteractCount(), (int) TEST_QPS);
    long prevTaskCount = executor.getExecutedTaskCount();
    executor.runFor(ONE_SECOND * TEST_NUM_CYCLES);
    // EventLoop continues by scheduling itself at the end. If executed task count remains the same,
    // then EventLoop hasn't re-scheduled itself.
    Assert.assertSame(executor.getExecutedTaskCount(), prevTaskCount);
}
Also used : ConstantQpsRateLimiter(com.linkedin.r2.transport.http.client.ConstantQpsRateLimiter) ClockedExecutor(com.linkedin.test.util.ClockedExecutor) None(com.linkedin.common.util.None) Test(org.testng.annotations.Test)

Example 40 with Timeout

use of com.linkedin.r2.util.Timeout in project rest.li by linkedin.

the class TestSmoothRateLimiter method testSubmitExceedsMaxBuffered.

@Test(timeOut = TEST_TIMEOUT)
public void testSubmitExceedsMaxBuffered() {
    SmoothRateLimiter rateLimiter = new SmoothRateLimiter(_scheduledExecutorService, _executor, _clock, _queue, 0, SmoothRateLimiter.BufferOverflowMode.DROP, RATE_LIMITER_NAME_TEST);
    rateLimiter.setRate(ONE_PERMIT_PER_PERIOD, ONE_SECOND_PERIOD, UNLIMITED_BURST);
    FutureCallback<None> callback = new FutureCallback<>();
    try {
        rateLimiter.submit(callback);
    } catch (RejectedExecutionException e) {
        Assert.assertFalse("The tasks should have been rejected and not run", callback.isDone());
        // success, the exception has been thrown as expected!
        return;
    }
    Assert.fail("It should have thrown a RejectedExecutionException");
}
Also used : SmoothRateLimiter(com.linkedin.r2.transport.http.client.SmoothRateLimiter) None(com.linkedin.common.util.None) FutureCallback(com.linkedin.common.callback.FutureCallback) RejectedExecutionException(java.util.concurrent.RejectedExecutionException) Test(org.testng.annotations.Test)

Aggregations

Test (org.testng.annotations.Test)78 RequestContext (com.linkedin.r2.message.RequestContext)46 CountDownLatch (java.util.concurrent.CountDownLatch)40 TimeoutException (java.util.concurrent.TimeoutException)40 None (com.linkedin.common.util.None)33 FutureCallback (com.linkedin.common.callback.FutureCallback)32 RestRequestBuilder (com.linkedin.r2.message.rest.RestRequestBuilder)26 StreamResponse (com.linkedin.r2.message.stream.StreamResponse)25 URI (java.net.URI)25 RestRequest (com.linkedin.r2.message.rest.RestRequest)21 StreamRequestBuilder (com.linkedin.r2.message.stream.StreamRequestBuilder)21 ByteString (com.linkedin.data.ByteString)19 HashMap (java.util.HashMap)19 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)19 RestResponse (com.linkedin.r2.message.rest.RestResponse)18 StreamRequest (com.linkedin.r2.message.stream.StreamRequest)17 ExecutionException (java.util.concurrent.ExecutionException)17 TransportClient (com.linkedin.r2.transport.common.bridge.client.TransportClient)15 IOException (java.io.IOException)15 TransportCallback (com.linkedin.r2.transport.common.bridge.common.TransportCallback)13