Search in sources :

Example 46 with AsyncEvent

use of javax.servlet.AsyncEvent in project presto by prestodb.

the class AsyncPageTransportServlet method processRequest.

protected void processRequest(String requestURI, TaskId taskId, OutputBufferId bufferId, long token, HttpServletRequest request, HttpServletResponse response) throws IOException {
    DataSize maxSize = DataSize.valueOf(request.getHeader(PRESTO_MAX_SIZE));
    AsyncContext asyncContext = request.startAsync(request, response);
    // wait time to get results
    Duration waitTime = randomizeWaitTime(DEFAULT_MAX_WAIT_TIME);
    asyncContext.setTimeout(waitTime.toMillis() + pageTransportTimeout.toMillis());
    asyncContext.addListener(new AsyncListener() {

        public void onComplete(AsyncEvent event) {
        }

        public void onError(AsyncEvent event) throws IOException {
            String errorMessage = format("Server error to process task result request %s : %s", requestURI, event.getThrowable().getMessage());
            log.error(event.getThrowable(), errorMessage);
            response.sendError(SC_INTERNAL_SERVER_ERROR, errorMessage);
        }

        public void onStartAsync(AsyncEvent event) {
        }

        public void onTimeout(AsyncEvent event) throws IOException {
            String errorMessage = format("Server timeout to process task result request: %s", requestURI);
            log.error(event.getThrowable(), errorMessage);
            response.sendError(SC_INTERNAL_SERVER_ERROR, errorMessage);
        }
    });
    ListenableFuture<BufferResult> bufferResultFuture = taskManager.getTaskResults(taskId, bufferId, token, maxSize);
    bufferResultFuture = addTimeout(bufferResultFuture, () -> BufferResult.emptyResults(taskManager.getTaskInstanceId(taskId), token, false), waitTime, timeoutExecutor);
    ServletOutputStream out = response.getOutputStream();
    addCallback(bufferResultFuture, new FutureCallback<BufferResult>() {

        @Override
        public void onSuccess(BufferResult bufferResult) {
            response.setHeader(CONTENT_TYPE, PRESTO_PAGES);
            response.setHeader(PRESTO_TASK_INSTANCE_ID, bufferResult.getTaskInstanceId());
            response.setHeader(PRESTO_PAGE_TOKEN, String.valueOf(bufferResult.getToken()));
            response.setHeader(PRESTO_PAGE_NEXT_TOKEN, String.valueOf(bufferResult.getNextToken()));
            response.setHeader(PRESTO_BUFFER_COMPLETE, String.valueOf(bufferResult.isBufferComplete()));
            List<SerializedPage> serializedPages = bufferResult.getSerializedPages();
            if (serializedPages.isEmpty()) {
                response.setStatus(SC_NO_CONTENT);
                asyncContext.complete();
            } else {
                int contentLength = (serializedPages.size() * PAGE_METADATA_SIZE) + serializedPages.stream().mapToInt(SerializedPage::getSizeInBytes).sum();
                response.setHeader(CONTENT_LENGTH, String.valueOf(contentLength));
                out.setWriteListener(new SerializedPageWriteListener(serializedPages, asyncContext, out));
            }
        }

        @Override
        public void onFailure(Throwable thrown) {
            String errorMessage = format("Error getting task result from TaskManager for request %s : %s", requestURI, thrown.getMessage());
            log.error(thrown, errorMessage);
            try {
                response.sendError(SC_INTERNAL_SERVER_ERROR, errorMessage);
            } catch (IOException e) {
                log.error(e, "Failed to send response with error code: %s", e.getMessage());
            }
            asyncContext.complete();
        }
    }, responseExecutor);
}
Also used : ServletOutputStream(javax.servlet.ServletOutputStream) AsyncContext(javax.servlet.AsyncContext) Duration(io.airlift.units.Duration) IOException(java.io.IOException) AsyncEvent(javax.servlet.AsyncEvent) BufferResult(com.facebook.presto.execution.buffer.BufferResult) DataSize(io.airlift.units.DataSize) AsyncListener(javax.servlet.AsyncListener) List(java.util.List)

Example 47 with AsyncEvent

use of javax.servlet.AsyncEvent in project java-chassis by ServiceComb.

the class TestRestAsyncListener method setup.

@Before
public void setup() {
    event = new AsyncEvent(context, requestEx, response);
    requestEx.setAttribute(RestConst.REST_REQUEST, requestEx);
    new MockUp<HttpServletResponse>(response) {

        @Mock
        void setContentType(String type) {
            contentType = type;
        }

        @Mock
        void setStatus(int sc) {
            statusCode = sc;
        }

        @Mock
        boolean isCommitted() {
            return committed;
        }

        @Mock
        PrintWriter getWriter() throws IOException {
            return printWriter;
        }

        @Mock
        void flushBuffer() throws IOException {
            flushed = true;
        }
    };
}
Also used : MockUp(mockit.MockUp) AsyncEvent(javax.servlet.AsyncEvent) Before(org.junit.Before)

Example 48 with AsyncEvent

use of javax.servlet.AsyncEvent in project rest.li by linkedin.

the class AbstractAsyncR2StreamServlet method service.

@Override
public void service(final HttpServletRequest req, final HttpServletResponse resp) throws ServletException, IOException {
    final AsyncContext ctx = req.startAsync(req, resp);
    ctx.setTimeout(_timeout);
    final WrappedAsyncContext wrappedCtx = new WrappedAsyncContext(ctx);
    final AsyncEventIOHandler ioHandler = new AsyncEventIOHandler(req.getInputStream(), resp.getOutputStream(), req.getRemoteAddr(), wrappedCtx, MAX_BUFFERED_CHUNKS, _logServletExceptions);
    final RequestContext requestContext = ServletHelper.readRequestContext(req);
    final StreamRequest streamRequest;
    try {
        streamRequest = ServletHelper.readFromServletRequest(req, ioHandler);
    } catch (URISyntaxException e) {
        ServletHelper.writeToServletError(resp, RestStatus.BAD_REQUEST, e.toString());
        wrappedCtx.complete();
        return;
    }
    final AtomicBoolean startedResponding = new AtomicBoolean(false);
    ctx.addListener(new AsyncListener() {

        @Override
        public void onTimeout(AsyncEvent event) throws IOException {
            LOG.error("Server timeout for request: " + formatURI(req.getRequestURI()));
            if (startedResponding.compareAndSet(false, true)) {
                LOG.info("Returning server timeout response");
                ServletHelper.writeToServletError(resp, RestStatus.INTERNAL_SERVER_ERROR, "Server timeout");
            } else {
                req.setAttribute(ASYNC_IOEXCEPTION, new ServletException("Server timeout"));
            }
            ioHandler.exitLoop();
            wrappedCtx.complete();
        }

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

        @Override
        public void onError(AsyncEvent event) throws IOException {
            LOG.error("Server error for request: " + formatURI(req.getRequestURI()));
            if (startedResponding.compareAndSet(false, true)) {
                LOG.info("Returning server error response");
                ServletHelper.writeToServletError(resp, RestStatus.INTERNAL_SERVER_ERROR, "Server error");
            } else {
                req.setAttribute(ASYNC_IOEXCEPTION, new ServletException("Server error"));
            }
            ioHandler.exitLoop();
            wrappedCtx.complete();
        }

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

        @Override
        public void onResponse(final TransportResponse<StreamResponse> response) {
            if (startedResponding.compareAndSet(false, true)) {
                ctx.start(new Runnable() {

                    @Override
                    public void run() {
                        try {
                            StreamResponse streamResponse = ServletHelper.writeResponseHeadersToServletResponse(response, resp);
                            streamResponse.getEntityStream().setReader(ioHandler);
                            ioHandler.loop();
                        } catch (Exception e) {
                            req.setAttribute(ASYNC_IOEXCEPTION, e);
                            wrappedCtx.complete();
                        }
                    }
                });
            } else {
                LOG.error("Dropped a response; this is mostly like because that AsyncContext timeout or error had already happened");
            }
        }
    };
    // we have to use a new thread and let this thread return to pool. otherwise the timeout won't start
    ctx.start(new Runnable() {

        @Override
        public void run() {
            try {
                getDispatcher().handleRequest(streamRequest, requestContext, callback);
                ioHandler.loop();
            } catch (Exception e) {
                req.setAttribute(ASYNC_IOEXCEPTION, e);
                wrappedCtx.complete();
            }
        }
    });
}
Also used : TransportCallback(com.linkedin.r2.transport.common.bridge.common.TransportCallback) StreamResponse(com.linkedin.r2.message.stream.StreamResponse) 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) ServletException(javax.servlet.ServletException) URISyntaxException(java.net.URISyntaxException) IOException(java.io.IOException) StreamRequest(com.linkedin.r2.message.stream.StreamRequest) ServletException(javax.servlet.ServletException) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) AsyncListener(javax.servlet.AsyncListener) RequestContext(com.linkedin.r2.message.RequestContext)

Example 49 with AsyncEvent

use of javax.servlet.AsyncEvent in project druid by druid-io.

the class SegmentListerResource method applyDataSegmentChangeRequests.

/**
 * This endpoint is used by HttpLoadQueuePeon to assign segment load/drop requests batch. This endpoint makes the
 * client wait till one of the following events occur. Note that this is implemented using async IO so no jetty
 * threads are held while in wait.
 *
 * (1) Given timeout elapses.
 * (2) Some load/drop request completed.
 *
 * It returns a map of "load/drop request -> SUCCESS/FAILED/PENDING status" for each request in the batch.
 */
@POST
@Path("/changeRequests")
@Produces({ MediaType.APPLICATION_JSON, SmileMediaTypes.APPLICATION_JACKSON_SMILE })
@Consumes({ MediaType.APPLICATION_JSON, SmileMediaTypes.APPLICATION_JACKSON_SMILE })
public void applyDataSegmentChangeRequests(@QueryParam("timeout") long timeout, List<DataSegmentChangeRequest> changeRequestList, @Context final HttpServletRequest req) throws IOException {
    if (loadDropRequestHandler == null) {
        sendErrorResponse(req, HttpServletResponse.SC_NOT_FOUND, "load/drop handler is not available.");
        return;
    }
    if (timeout <= 0) {
        sendErrorResponse(req, HttpServletResponse.SC_BAD_REQUEST, "timeout must be positive.");
        return;
    }
    if (changeRequestList == null || changeRequestList.isEmpty()) {
        sendErrorResponse(req, HttpServletResponse.SC_BAD_REQUEST, "No change requests provided.");
        return;
    }
    final ResponseContext context = createContext(req.getHeader("Accept"));
    final ListenableFuture<List<SegmentLoadDropHandler.DataSegmentChangeRequestAndStatus>> future = loadDropRequestHandler.processBatch(changeRequestList);
    final AsyncContext asyncContext = req.startAsync();
    asyncContext.addListener(new AsyncListener() {

        @Override
        public void onComplete(AsyncEvent event) {
        }

        @Override
        public void onTimeout(AsyncEvent event) {
            // HTTP 204 NO_CONTENT is sent to the client.
            future.cancel(true);
            event.getAsyncContext().complete();
        }

        @Override
        public void onError(AsyncEvent event) {
        }

        @Override
        public void onStartAsync(AsyncEvent event) {
        }
    });
    Futures.addCallback(future, new FutureCallback<List<SegmentLoadDropHandler.DataSegmentChangeRequestAndStatus>>() {

        @Override
        public void onSuccess(List<SegmentLoadDropHandler.DataSegmentChangeRequestAndStatus> result) {
            try {
                HttpServletResponse response = (HttpServletResponse) asyncContext.getResponse();
                response.setStatus(HttpServletResponse.SC_OK);
                context.inputMapper.writerWithType(HttpLoadQueuePeon.RESPONSE_ENTITY_TYPE_REF).writeValue(asyncContext.getResponse().getOutputStream(), result);
                asyncContext.complete();
            } catch (Exception ex) {
                log.debug(ex, "Request timed out or closed already.");
            }
        }

        @Override
        public void onFailure(Throwable th) {
            try {
                HttpServletResponse response = (HttpServletResponse) asyncContext.getResponse();
                if (th instanceof IllegalArgumentException) {
                    response.sendError(HttpServletResponse.SC_BAD_REQUEST, th.getMessage());
                } else {
                    response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, th.getMessage());
                }
                asyncContext.complete();
            } catch (Exception ex) {
                log.debug(ex, "Request timed out or closed already.");
            }
        }
    });
    asyncContext.setTimeout(timeout);
}
Also used : SegmentLoadDropHandler(org.apache.druid.server.coordination.SegmentLoadDropHandler) HttpServletResponse(javax.servlet.http.HttpServletResponse) AsyncContext(javax.servlet.AsyncContext) AsyncEvent(javax.servlet.AsyncEvent) IOException(java.io.IOException) AsyncListener(javax.servlet.AsyncListener) List(java.util.List) Path(javax.ws.rs.Path) POST(javax.ws.rs.POST) Produces(javax.ws.rs.Produces) Consumes(javax.ws.rs.Consumes)

Example 50 with AsyncEvent

use of javax.servlet.AsyncEvent in project druid by druid-io.

the class TaskManagementResource method getWorkerState.

/**
 * This endpoint is used by HttpRemoteTaskRunner to keep an up-to-date state of the worker wrt to the tasks it is
 * running, completed etc and other metadata such as its enabled/disabled status.
 *
 * Here is how, this is used.
 *
 * (1) Client sends first request /druid/internal/v1/worker?counter=-1&timeout=<timeout>
 * Server responds with current list of running/completed tasks and metadata. And, a <counter,hash> pair.
 *
 * (2) Client sends subsequent requests /druid/internal/v1/worker?counter=<counter>&hash=<hash>&timeout=<timeout>
 * Where <counter,hash> values are used from the last response. Server responds with changes since then.
 *
 * This endpoint makes the client wait till either there is some update or given timeout elapses.
 *
 * So, clients keep on sending next request immediately after receiving the response in order to keep the state of
 * this server up-to-date.
 *
 * @param counter counter received in last response.
 * @param hash hash received in last response.
 * @param timeout after which response is sent even if there are no new segment updates.
 * @param req
 * @return null to avoid "MUST return a non-void type" warning.
 * @throws IOException
 */
@GET
@Produces({ MediaType.APPLICATION_JSON, SmileMediaTypes.APPLICATION_JACKSON_SMILE })
public Void getWorkerState(@QueryParam("counter") long counter, @QueryParam("hash") long hash, @QueryParam("timeout") long timeout, @Context final HttpServletRequest req) throws IOException {
    if (timeout <= 0) {
        sendErrorResponse(req, HttpServletResponse.SC_BAD_REQUEST, "timeout must be positive.");
        return null;
    }
    final ResponseContext context = createContext(req.getHeader("Accept"));
    final ListenableFuture<ChangeRequestsSnapshot<WorkerHistoryItem>> future = workerTaskManager.getChangesSince(new ChangeRequestHistory.Counter(counter, hash));
    final AsyncContext asyncContext = req.startAsync();
    asyncContext.addListener(new AsyncListener() {

        @Override
        public void onComplete(AsyncEvent event) {
        }

        @Override
        public void onTimeout(AsyncEvent event) {
            // HTTP 204 NO_CONTENT is sent to the client.
            future.cancel(true);
            event.getAsyncContext().complete();
        }

        @Override
        public void onError(AsyncEvent event) {
        }

        @Override
        public void onStartAsync(AsyncEvent event) {
        }
    });
    Futures.addCallback(future, new FutureCallback<ChangeRequestsSnapshot>() {

        @Override
        public void onSuccess(ChangeRequestsSnapshot result) {
            try {
                HttpServletResponse response = (HttpServletResponse) asyncContext.getResponse();
                response.setStatus(HttpServletResponse.SC_OK);
                context.inputMapper.writerWithType(WorkerHolder.WORKER_SYNC_RESP_TYPE_REF).writeValue(asyncContext.getResponse().getOutputStream(), result);
                asyncContext.complete();
            } catch (Exception ex) {
                log.debug(ex, "Request timed out or closed already.");
            }
        }

        @Override
        public void onFailure(Throwable th) {
            try {
                HttpServletResponse response = (HttpServletResponse) asyncContext.getResponse();
                if (th instanceof IllegalArgumentException) {
                    response.sendError(HttpServletResponse.SC_BAD_REQUEST, th.getMessage());
                } else {
                    response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, th.getMessage());
                }
                asyncContext.complete();
            } catch (Exception ex) {
                log.debug(ex, "Request timed out or closed already.");
            }
        }
    });
    asyncContext.setTimeout(timeout);
    return null;
}
Also used : ChangeRequestHistory(org.apache.druid.server.coordination.ChangeRequestHistory) HttpServletResponse(javax.servlet.http.HttpServletResponse) AsyncContext(javax.servlet.AsyncContext) AsyncEvent(javax.servlet.AsyncEvent) IOException(java.io.IOException) AsyncListener(javax.servlet.AsyncListener) ChangeRequestsSnapshot(org.apache.druid.server.coordination.ChangeRequestsSnapshot) Produces(javax.ws.rs.Produces) GET(javax.ws.rs.GET)

Aggregations

AsyncEvent (javax.servlet.AsyncEvent)51 IOException (java.io.IOException)38 AsyncContext (javax.servlet.AsyncContext)35 AsyncListener (javax.servlet.AsyncListener)32 HttpServletResponse (javax.servlet.http.HttpServletResponse)23 HttpServletRequest (javax.servlet.http.HttpServletRequest)20 Test (org.junit.Test)19 ServletException (javax.servlet.ServletException)12 HttpServlet (javax.servlet.http.HttpServlet)9 CountDownLatch (java.util.concurrent.CountDownLatch)6 AtomicReference (java.util.concurrent.atomic.AtomicReference)6 ServletResponse (javax.servlet.ServletResponse)5 OutputStream (java.io.OutputStream)4 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)4 FilterChain (javax.servlet.FilterChain)4 Socket (java.net.Socket)3 URISyntaxException (java.net.URISyntaxException)3 ArrayList (java.util.ArrayList)3 CyclicBarrier (java.util.concurrent.CyclicBarrier)3 HttpTester (org.eclipse.jetty.http.HttpTester)3