Search in sources :

Example 1 with AsyncListener

use of javax.servlet.AsyncListener in project jetty.project by eclipse.

the class StatisticsHandlerTest method testSuspendResume.

@Test
public void testSuspendResume() throws Exception {
    final long dispatchTime = 10;
    final long requestTime = 50;
    final AtomicReference<AsyncContext> asyncHolder = new AtomicReference<>();
    final CyclicBarrier[] barrier = { new CyclicBarrier(2), new CyclicBarrier(2), new CyclicBarrier(2) };
    _statsHandler.setHandler(new AbstractHandler() {

        @Override
        public void handle(String path, Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse) throws IOException, ServletException {
            request.setHandled(true);
            try {
                barrier[0].await();
                Thread.sleep(dispatchTime);
                if (asyncHolder.get() == null)
                    asyncHolder.set(request.startAsync());
            } catch (Exception x) {
                throw new ServletException(x);
            } finally {
                try {
                    barrier[1].await();
                } catch (Exception ignored) {
                }
            }
        }
    });
    _server.start();
    String request = "GET / HTTP/1.1\r\n" + "Host: localhost\r\n" + "\r\n";
    _connector.executeRequest(request);
    barrier[0].await();
    assertEquals(1, _statistics.getConnections());
    assertEquals(1, _statsHandler.getRequests());
    assertEquals(1, _statsHandler.getRequestsActive());
    assertEquals(1, _statsHandler.getDispatched());
    assertEquals(1, _statsHandler.getDispatchedActive());
    barrier[1].await();
    assertTrue(_latchHandler.await());
    assertNotNull(asyncHolder.get());
    assertEquals(1, _statsHandler.getRequests());
    assertEquals(1, _statsHandler.getRequestsActive());
    assertEquals(1, _statsHandler.getDispatched());
    assertEquals(0, _statsHandler.getDispatchedActive());
    _latchHandler.reset();
    barrier[0].reset();
    barrier[1].reset();
    Thread.sleep(requestTime);
    asyncHolder.get().addListener(new AsyncListener() {

        @Override
        public void onTimeout(AsyncEvent event) throws IOException {
        }

        @Override
        public void onStartAsync(AsyncEvent event) throws IOException {
        }

        @Override
        public void onError(AsyncEvent event) throws IOException {
        }

        @Override
        public void onComplete(AsyncEvent event) throws IOException {
            try {
                barrier[2].await();
            } catch (Exception ignored) {
            }
        }
    });
    asyncHolder.get().dispatch();
    // entered app handler
    barrier[0].await();
    assertEquals(1, _statistics.getConnections());
    assertEquals(1, _statsHandler.getRequests());
    assertEquals(1, _statsHandler.getRequestsActive());
    assertEquals(2, _statsHandler.getDispatched());
    assertEquals(1, _statsHandler.getDispatchedActive());
    // exiting app handler
    barrier[1].await();
    // exited stats handler
    assertTrue(_latchHandler.await());
    // onComplete called
    barrier[2].await();
    assertEquals(1, _statsHandler.getRequests());
    assertEquals(0, _statsHandler.getRequestsActive());
    assertEquals(2, _statsHandler.getDispatched());
    assertEquals(0, _statsHandler.getDispatchedActive());
    assertEquals(1, _statsHandler.getAsyncRequests());
    assertEquals(1, _statsHandler.getAsyncDispatches());
    assertEquals(0, _statsHandler.getExpires());
    assertEquals(1, _statsHandler.getResponses2xx());
    assertThat(_statsHandler.getRequestTimeTotal(), greaterThanOrEqualTo(requestTime * 3 / 4));
    assertEquals(_statsHandler.getRequestTimeTotal(), _statsHandler.getRequestTimeMax());
    assertEquals(_statsHandler.getRequestTimeTotal(), _statsHandler.getRequestTimeMean(), 0.01);
    assertThat(_statsHandler.getDispatchedTimeTotal(), greaterThanOrEqualTo(dispatchTime * 2 * 3 / 4));
    assertTrue(_statsHandler.getDispatchedTimeMean() + dispatchTime <= _statsHandler.getDispatchedTimeTotal());
    assertTrue(_statsHandler.getDispatchedTimeMax() + dispatchTime <= _statsHandler.getDispatchedTimeTotal());
}
Also used : Request(org.eclipse.jetty.server.Request) HttpServletRequest(javax.servlet.http.HttpServletRequest) HttpServletResponse(javax.servlet.http.HttpServletResponse) AtomicReference(java.util.concurrent.atomic.AtomicReference) AsyncContext(javax.servlet.AsyncContext) IOException(java.io.IOException) AsyncEvent(javax.servlet.AsyncEvent) ServletException(javax.servlet.ServletException) IOException(java.io.IOException) CyclicBarrier(java.util.concurrent.CyclicBarrier) HttpServletRequest(javax.servlet.http.HttpServletRequest) ServletException(javax.servlet.ServletException) AsyncListener(javax.servlet.AsyncListener) Test(org.junit.Test)

Example 2 with AsyncListener

use of javax.servlet.AsyncListener in project jetty.project by eclipse.

the class StatisticsHandlerTest method testSuspendComplete.

@Test
public void testSuspendComplete() throws Exception {
    final long dispatchTime = 10;
    final AtomicReference<AsyncContext> asyncHolder = new AtomicReference<>();
    final CyclicBarrier[] barrier = { new CyclicBarrier(2), new CyclicBarrier(2) };
    final CountDownLatch latch = new CountDownLatch(1);
    _statsHandler.setHandler(new AbstractHandler() {

        @Override
        public void handle(String path, Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse) throws IOException, ServletException {
            request.setHandled(true);
            try {
                barrier[0].await();
                Thread.sleep(dispatchTime);
                if (asyncHolder.get() == null) {
                    AsyncContext async = request.startAsync();
                    asyncHolder.set(async);
                }
            } catch (Exception x) {
                throw new ServletException(x);
            } finally {
                try {
                    barrier[1].await();
                } catch (Exception ignored) {
                }
            }
        }
    });
    _server.start();
    String request = "GET / HTTP/1.1\r\n" + "Host: localhost\r\n" + "\r\n";
    _connector.executeRequest(request);
    barrier[0].await();
    assertEquals(1, _statistics.getConnections());
    assertEquals(1, _statsHandler.getRequests());
    assertEquals(1, _statsHandler.getRequestsActive());
    assertEquals(1, _statsHandler.getDispatched());
    assertEquals(1, _statsHandler.getDispatchedActive());
    barrier[1].await();
    assertTrue(_latchHandler.await());
    assertNotNull(asyncHolder.get());
    assertEquals(1, _statsHandler.getRequests());
    assertEquals(1, _statsHandler.getRequestsActive());
    assertEquals(1, _statsHandler.getDispatched());
    assertEquals(0, _statsHandler.getDispatchedActive());
    asyncHolder.get().addListener(new AsyncListener() {

        @Override
        public void onTimeout(AsyncEvent event) throws IOException {
        }

        @Override
        public void onStartAsync(AsyncEvent event) throws IOException {
        }

        @Override
        public void onError(AsyncEvent event) throws IOException {
        }

        @Override
        public void onComplete(AsyncEvent event) throws IOException {
            try {
                latch.countDown();
            } catch (Exception ignored) {
            }
        }
    });
    long requestTime = 20;
    Thread.sleep(requestTime);
    asyncHolder.get().complete();
    latch.await();
    assertEquals(1, _statsHandler.getRequests());
    assertEquals(0, _statsHandler.getRequestsActive());
    assertEquals(1, _statsHandler.getDispatched());
    assertEquals(0, _statsHandler.getDispatchedActive());
    assertEquals(1, _statsHandler.getAsyncRequests());
    assertEquals(0, _statsHandler.getAsyncDispatches());
    assertEquals(0, _statsHandler.getExpires());
    assertEquals(1, _statsHandler.getResponses2xx());
    assertTrue(_statsHandler.getRequestTimeTotal() >= (dispatchTime + requestTime) * 3 / 4);
    assertEquals(_statsHandler.getRequestTimeTotal(), _statsHandler.getRequestTimeMax());
    assertEquals(_statsHandler.getRequestTimeTotal(), _statsHandler.getRequestTimeMean(), 0.01);
    assertTrue(_statsHandler.getDispatchedTimeTotal() >= dispatchTime * 3 / 4);
    assertTrue(_statsHandler.getDispatchedTimeTotal() < _statsHandler.getRequestTimeTotal());
    assertEquals(_statsHandler.getDispatchedTimeTotal(), _statsHandler.getDispatchedTimeMax());
    assertEquals(_statsHandler.getDispatchedTimeTotal(), _statsHandler.getDispatchedTimeMean(), 0.01);
}
Also used : Request(org.eclipse.jetty.server.Request) HttpServletRequest(javax.servlet.http.HttpServletRequest) HttpServletResponse(javax.servlet.http.HttpServletResponse) AtomicReference(java.util.concurrent.atomic.AtomicReference) AsyncContext(javax.servlet.AsyncContext) IOException(java.io.IOException) CountDownLatch(java.util.concurrent.CountDownLatch) AsyncEvent(javax.servlet.AsyncEvent) ServletException(javax.servlet.ServletException) IOException(java.io.IOException) CyclicBarrier(java.util.concurrent.CyclicBarrier) HttpServletRequest(javax.servlet.http.HttpServletRequest) ServletException(javax.servlet.ServletException) AsyncListener(javax.servlet.AsyncListener) Test(org.junit.Test)

Example 3 with AsyncListener

use of javax.servlet.AsyncListener in project jetty.project by eclipse.

the class AsyncContextListenersTest method testListenerAddedFromListener.

@SuppressWarnings("Duplicates")
@Test
public void testListenerAddedFromListener() throws Exception {
    final AtomicReference<CountDownLatch> completes = new AtomicReference<>(new CountDownLatch(1));
    String path = "/path";
    prepare(path, new HttpServlet() {

        @Override
        protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            AsyncContext asyncContext = request.startAsync(request, response);
            asyncContext.addListener(new AsyncListener() {

                @Override
                public void onStartAsync(AsyncEvent event) throws IOException {
                    // This method should not be invoked because we add the
                    // listener *after* having called startAsync(), but we
                    // add a listener to be sure it's not called (it will
                    // screw up the completes count and test will fail).
                    event.getAsyncContext().addListener(this);
                }

                @Override
                public void onComplete(AsyncEvent event) throws IOException {
                    completes.get().countDown();
                }

                @Override
                public void onTimeout(AsyncEvent event) throws IOException {
                }

                @Override
                public void onError(AsyncEvent event) throws IOException {
                }
            });
            asyncContext.complete();
        }
    });
    try (Socket socket = new Socket("localhost", _connector.getLocalPort())) {
        OutputStream output = socket.getOutputStream();
        String request = "" + "GET " + path + " HTTP/1.1\r\n" + "Host: localhost\r\n" + "\r\n";
        output.write(request.getBytes(StandardCharsets.UTF_8));
        output.flush();
        HttpTester.Input input = HttpTester.from(socket.getInputStream());
        HttpTester.Response response = HttpTester.parseResponse(input);
        Assert.assertEquals(200, response.getStatus());
        completes.get().await(10, TimeUnit.SECONDS);
        // Send a second request
        completes.set(new CountDownLatch(1));
        output.write(request.getBytes(StandardCharsets.UTF_8));
        output.flush();
        response = HttpTester.parseResponse(input);
        Assert.assertEquals(200, response.getStatus());
        completes.get().await(10, TimeUnit.SECONDS);
    }
}
Also used : HttpServlet(javax.servlet.http.HttpServlet) OutputStream(java.io.OutputStream) HttpServletResponse(javax.servlet.http.HttpServletResponse) AtomicReference(java.util.concurrent.atomic.AtomicReference) AsyncContext(javax.servlet.AsyncContext) IOException(java.io.IOException) CountDownLatch(java.util.concurrent.CountDownLatch) AsyncEvent(javax.servlet.AsyncEvent) HttpTester(org.eclipse.jetty.http.HttpTester) HttpServletRequest(javax.servlet.http.HttpServletRequest) ServletException(javax.servlet.ServletException) AsyncListener(javax.servlet.AsyncListener) Socket(java.net.Socket) Test(org.junit.Test)

Example 4 with AsyncListener

use of javax.servlet.AsyncListener in project jetty.project by eclipse.

the class AsyncServletTest method testStartAsyncThenServerIdleTimeout.

private void testStartAsyncThenServerIdleTimeout(long sessionTimeout, long streamTimeout) throws Exception {
    prepareServer(new HTTP2ServerConnectionFactory(new HttpConfiguration()) {

        @Override
        protected ServerSessionListener newSessionListener(Connector connector, EndPoint endPoint) {
            return new HTTPServerSessionListener(connector, endPoint) {

                @Override
                public Stream.Listener onNewStream(Stream stream, HeadersFrame frame) {
                    stream.setIdleTimeout(streamTimeout);
                    return super.onNewStream(stream, frame);
                }
            };
        }
    });
    connector.setIdleTimeout(sessionTimeout);
    ServletContextHandler context = new ServletContextHandler(server, "/");
    long timeout = Math.min(sessionTimeout, streamTimeout);
    CountDownLatch errorLatch = new CountDownLatch(1);
    context.addServlet(new ServletHolder(new HttpServlet() {

        @Override
        protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            AsyncContext asyncContext = (AsyncContext) request.getAttribute(AsyncContext.class.getName());
            if (asyncContext == null) {
                AsyncContext context = request.startAsync();
                context.setTimeout(2 * timeout);
                request.setAttribute(AsyncContext.class.getName(), context);
                context.addListener(new AsyncListener() {

                    @Override
                    public void onComplete(AsyncEvent event) throws IOException {
                    }

                    @Override
                    public void onTimeout(AsyncEvent event) throws IOException {
                        event.getAsyncContext().complete();
                    }

                    @Override
                    public void onError(AsyncEvent event) throws IOException {
                        errorLatch.countDown();
                    }

                    @Override
                    public void onStartAsync(AsyncEvent event) throws IOException {
                    }
                });
            } else {
                throw new ServletException();
            }
        }
    }), servletPath + "/*");
    server.start();
    prepareClient();
    client.start();
    Session session = newClient(new Session.Listener.Adapter());
    HttpFields fields = new HttpFields();
    MetaData.Request metaData = newRequest("GET", fields);
    HeadersFrame frame = new HeadersFrame(metaData, null, true);
    CountDownLatch clientLatch = new CountDownLatch(1);
    session.newStream(frame, new Promise.Adapter<>(), new Stream.Listener.Adapter() {

        @Override
        public void onHeaders(Stream stream, HeadersFrame frame) {
            MetaData.Response response = (MetaData.Response) frame.getMetaData();
            if (response.getStatus() == HttpStatus.OK_200 && frame.isEndStream())
                clientLatch.countDown();
        }
    });
    // When the server idle times out, but the request has been dispatched
    // then the server must ignore the idle timeout as per Servlet semantic.
    Assert.assertFalse(errorLatch.await(2 * timeout, TimeUnit.MILLISECONDS));
    Assert.assertTrue(clientLatch.await(2 * timeout, TimeUnit.MILLISECONDS));
}
Also used : Connector(org.eclipse.jetty.server.Connector) AsyncListener(javax.servlet.AsyncListener) ServerSessionListener(org.eclipse.jetty.http2.api.server.ServerSessionListener) ServletHolder(org.eclipse.jetty.servlet.ServletHolder) AsyncContext(javax.servlet.AsyncContext) HttpConfiguration(org.eclipse.jetty.server.HttpConfiguration) EndPoint(org.eclipse.jetty.io.EndPoint) HeadersFrame(org.eclipse.jetty.http2.frames.HeadersFrame) HttpServletRequest(javax.servlet.http.HttpServletRequest) ServletException(javax.servlet.ServletException) MetaData(org.eclipse.jetty.http.MetaData) HttpFields(org.eclipse.jetty.http.HttpFields) ByteArrayOutputStream(java.io.ByteArrayOutputStream) Stream(org.eclipse.jetty.http2.api.Stream) HttpServlet(javax.servlet.http.HttpServlet) HttpServletResponse(javax.servlet.http.HttpServletResponse) HTTP2ServerConnectionFactory(org.eclipse.jetty.http2.server.HTTP2ServerConnectionFactory) IOException(java.io.IOException) CountDownLatch(java.util.concurrent.CountDownLatch) AsyncEvent(javax.servlet.AsyncEvent) HttpServletResponse(javax.servlet.http.HttpServletResponse) Promise(org.eclipse.jetty.util.Promise) FuturePromise(org.eclipse.jetty.util.FuturePromise) AsyncListener(javax.servlet.AsyncListener) ServletContextHandler(org.eclipse.jetty.servlet.ServletContextHandler) ServerSessionListener(org.eclipse.jetty.http2.api.server.ServerSessionListener) Session(org.eclipse.jetty.http2.api.Session)

Example 5 with AsyncListener

use of javax.servlet.AsyncListener in project jetty.project by eclipse.

the class AsyncContextState method addListener.

@Override
public void addListener(final AsyncListener listener, final ServletRequest request, final ServletResponse response) {
    AsyncListener wrap = new AsyncListener() {

        @Override
        public void onTimeout(AsyncEvent event) throws IOException {
            listener.onTimeout(new AsyncEvent(event.getAsyncContext(), request, response, event.getThrowable()));
        }

        @Override
        public void onStartAsync(AsyncEvent event) throws IOException {
            listener.onStartAsync(new AsyncEvent(event.getAsyncContext(), request, response, event.getThrowable()));
        }

        @Override
        public void onError(AsyncEvent event) throws IOException {
            listener.onError(new AsyncEvent(event.getAsyncContext(), request, response, event.getThrowable()));
        }

        @Override
        public void onComplete(AsyncEvent event) throws IOException {
            listener.onComplete(new AsyncEvent(event.getAsyncContext(), request, response, event.getThrowable()));
        }
    };
    state().addListener(wrap);
}
Also used : AsyncListener(javax.servlet.AsyncListener) AsyncEvent(javax.servlet.AsyncEvent)

Aggregations

AsyncListener (javax.servlet.AsyncListener)45 AsyncContext (javax.servlet.AsyncContext)32 AsyncEvent (javax.servlet.AsyncEvent)30 IOException (java.io.IOException)28 HttpServletResponse (javax.servlet.http.HttpServletResponse)16 HttpServletRequest (javax.servlet.http.HttpServletRequest)14 ServletException (javax.servlet.ServletException)12 Test (org.junit.Test)12 AtomicReference (java.util.concurrent.atomic.AtomicReference)7 CountDownLatch (java.util.concurrent.CountDownLatch)5 HttpServlet (javax.servlet.http.HttpServlet)5 OutputStream (java.io.OutputStream)4 Socket (java.net.Socket)3 URISyntaxException (java.net.URISyntaxException)3 CyclicBarrier (java.util.concurrent.CyclicBarrier)3 Request (org.eclipse.jetty.server.Request)3 Locker (org.eclipse.jetty.util.thread.Locker)3 RequestContext (com.linkedin.r2.message.RequestContext)2 TransportCallback (com.linkedin.r2.transport.common.bridge.common.TransportCallback)2 TransportResponse (com.linkedin.r2.transport.common.bridge.common.TransportResponse)2