use of org.apache.catalina.core.AsyncContextImpl in project tomcat by apache.
the class CoyoteAdapter method asyncDispatch.
// -------------------------------------------------------- Adapter Methods
@Override
public boolean asyncDispatch(org.apache.coyote.Request req, org.apache.coyote.Response res, SocketEvent status) throws Exception {
Request request = (Request) req.getNote(ADAPTER_NOTES);
Response response = (Response) res.getNote(ADAPTER_NOTES);
if (request == null) {
throw new IllegalStateException("Dispatch may only happen on an existing request.");
}
boolean success = true;
AsyncContextImpl asyncConImpl = request.getAsyncContextInternal();
req.getRequestProcessor().setWorkerThreadName(THREAD_NAME.get());
try {
if (!request.isAsync()) {
// Error or timeout
// Lift any suspension (e.g. if sendError() was used by an async
// request) to allow the response to be written to the client
response.setSuspended(false);
}
if (status == SocketEvent.TIMEOUT) {
if (!asyncConImpl.timeout()) {
asyncConImpl.setErrorState(null, false);
}
} else if (status == SocketEvent.ERROR) {
// An I/O error occurred on a non-container thread which means
// that the socket needs to be closed so set success to false to
// trigger a close
success = false;
Throwable t = (Throwable) req.getAttribute(RequestDispatcher.ERROR_EXCEPTION);
req.getAttributes().remove(RequestDispatcher.ERROR_EXCEPTION);
ClassLoader oldCL = null;
try {
oldCL = request.getContext().bind(false, null);
if (req.getReadListener() != null) {
req.getReadListener().onError(t);
}
if (res.getWriteListener() != null) {
res.getWriteListener().onError(t);
}
} finally {
request.getContext().unbind(false, oldCL);
}
if (t != null) {
asyncConImpl.setErrorState(t, true);
}
}
// Check to see if non-blocking writes or reads are being used
if (!request.isAsyncDispatching() && request.isAsync()) {
WriteListener writeListener = res.getWriteListener();
ReadListener readListener = req.getReadListener();
if (writeListener != null && status == SocketEvent.OPEN_WRITE) {
ClassLoader oldCL = null;
try {
oldCL = request.getContext().bind(false, null);
res.onWritePossible();
if (request.isFinished() && req.sendAllDataReadEvent() && readListener != null) {
readListener.onAllDataRead();
}
} catch (Throwable t) {
ExceptionUtils.handleThrowable(t);
writeListener.onError(t);
success = false;
} finally {
request.getContext().unbind(false, oldCL);
}
} else if (readListener != null && status == SocketEvent.OPEN_READ) {
ClassLoader oldCL = null;
try {
oldCL = request.getContext().bind(false, null);
// onDataAvailable() is not called in this case.
if (!request.isFinished()) {
readListener.onDataAvailable();
}
if (request.isFinished() && req.sendAllDataReadEvent()) {
readListener.onAllDataRead();
}
} catch (Throwable t) {
ExceptionUtils.handleThrowable(t);
readListener.onError(t);
success = false;
} finally {
request.getContext().unbind(false, oldCL);
}
}
}
// if the application doesn't define one)?
if (!request.isAsyncDispatching() && request.isAsync() && response.isErrorReportRequired()) {
connector.getService().getContainer().getPipeline().getFirst().invoke(request, response);
}
if (request.isAsyncDispatching()) {
connector.getService().getContainer().getPipeline().getFirst().invoke(request, response);
Throwable t = (Throwable) request.getAttribute(RequestDispatcher.ERROR_EXCEPTION);
if (t != null) {
asyncConImpl.setErrorState(t, true);
}
}
if (!request.isAsync()) {
request.finishRequest();
response.finishResponse();
}
// Check to see if the processor is in an error state. If it is,
// bail out now.
AtomicBoolean error = new AtomicBoolean(false);
res.action(ActionCode.IS_ERROR, error);
if (error.get()) {
if (request.isAsyncCompleting()) {
// Connection will be forcibly closed which will prevent
// completion happening at the usual point. Need to trigger
// call to onComplete() here.
res.action(ActionCode.ASYNC_POST_PROCESS, null);
}
success = false;
}
} catch (IOException e) {
success = false;
// Ignore
} catch (Throwable t) {
ExceptionUtils.handleThrowable(t);
success = false;
log.error(sm.getString("coyoteAdapter.asyncDispatch"), t);
} finally {
if (!success) {
res.setStatus(500);
}
// Access logging
if (!success || !request.isAsync()) {
long time = 0;
if (req.getStartTime() != -1) {
time = System.currentTimeMillis() - req.getStartTime();
}
if (request.getMappingData().context != null) {
request.getMappingData().context.logAccess(request, response, time, false);
} else {
log(req, res, time);
}
}
req.getRequestProcessor().setWorkerThreadName(null);
// Recycle the wrapper request and response
if (!success || !request.isAsync()) {
request.recycle();
response.recycle();
}
}
return success;
}
use of org.apache.catalina.core.AsyncContextImpl in project tomcat by apache.
the class Request method startAsync.
@Override
public AsyncContext startAsync(ServletRequest request, ServletResponse response) {
if (!isAsyncSupported()) {
throw new IllegalStateException(sm.getString("request.asyncNotSupported"));
}
if (asyncContext == null) {
asyncContext = new AsyncContextImpl(this);
}
asyncContext.setStarted(getContext(), request, response, request == getRequest() && response == getResponse().getResponse());
asyncContext.setTimeout(getConnector().getAsyncTimeout());
return asyncContext;
}
Aggregations