Polish
This commit is contained in:
parent
ece4815459
commit
c0f2017262
|
@ -18,6 +18,8 @@ package org.springframework.http.server.reactive;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import javax.servlet.AsyncContext;
|
import javax.servlet.AsyncContext;
|
||||||
|
import javax.servlet.AsyncEvent;
|
||||||
|
import javax.servlet.AsyncListener;
|
||||||
import javax.servlet.Servlet;
|
import javax.servlet.Servlet;
|
||||||
import javax.servlet.ServletConfig;
|
import javax.servlet.ServletConfig;
|
||||||
import javax.servlet.ServletRequest;
|
import javax.servlet.ServletRequest;
|
||||||
|
@ -106,6 +108,8 @@ public class ServletHttpHandlerAdapter implements Servlet {
|
||||||
ServerHttpRequest httpRequest = createRequest(((HttpServletRequest) request), asyncContext);
|
ServerHttpRequest httpRequest = createRequest(((HttpServletRequest) request), asyncContext);
|
||||||
ServerHttpResponse httpResponse = createResponse(((HttpServletResponse) response), asyncContext);
|
ServerHttpResponse httpResponse = createResponse(((HttpServletResponse) response), asyncContext);
|
||||||
|
|
||||||
|
asyncContext.addListener(TIMEOUT_LISTENER);
|
||||||
|
|
||||||
HandlerResultSubscriber subscriber = new HandlerResultSubscriber(asyncContext);
|
HandlerResultSubscriber subscriber = new HandlerResultSubscriber(asyncContext);
|
||||||
this.httpHandler.handle(httpRequest, httpResponse).subscribe(subscriber);
|
this.httpHandler.handle(httpRequest, httpResponse).subscribe(subscriber);
|
||||||
}
|
}
|
||||||
|
@ -146,14 +150,40 @@ public class ServletHttpHandlerAdapter implements Servlet {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private final static AsyncListener TIMEOUT_LISTENER = new AsyncListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onTimeout(AsyncEvent event) throws IOException {
|
||||||
|
event.getAsyncContext().complete();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onError(AsyncEvent event) throws IOException {
|
||||||
|
event.getAsyncContext().complete();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStartAsync(AsyncEvent event) throws IOException {
|
||||||
|
// no-op
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onComplete(AsyncEvent event) throws IOException {
|
||||||
|
// no-op
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
private class HandlerResultSubscriber implements Subscriber<Void> {
|
private class HandlerResultSubscriber implements Subscriber<Void> {
|
||||||
|
|
||||||
private final AsyncContext asyncContext;
|
private final AsyncContext asyncContext;
|
||||||
|
|
||||||
|
|
||||||
public HandlerResultSubscriber(AsyncContext asyncContext) {
|
public HandlerResultSubscriber(AsyncContext asyncContext) {
|
||||||
this.asyncContext = asyncContext;
|
this.asyncContext = asyncContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onSubscribe(Subscription subscription) {
|
public void onSubscribe(Subscription subscription) {
|
||||||
subscription.request(Long.MAX_VALUE);
|
subscription.request(Long.MAX_VALUE);
|
||||||
|
@ -166,32 +196,33 @@ public class ServletHttpHandlerAdapter implements Servlet {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onError(Throwable ex) {
|
public void onError(Throwable ex) {
|
||||||
ServletRequest request = getRequest();
|
runIfAsyncNotComplete(() -> {
|
||||||
if (request != null && request.isAsyncStarted()) {
|
|
||||||
logger.error("Could not complete request", ex);
|
logger.error("Could not complete request", ex);
|
||||||
HttpServletResponse response = (HttpServletResponse) this.asyncContext.getResponse();
|
HttpServletResponse response = (HttpServletResponse) this.asyncContext.getResponse();
|
||||||
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
|
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
|
||||||
this.asyncContext.complete();
|
this.asyncContext.complete();
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onComplete() {
|
public void onComplete() {
|
||||||
ServletRequest request = getRequest();
|
runIfAsyncNotComplete(() -> {
|
||||||
if (request != null && request.isAsyncStarted()) {
|
|
||||||
logger.debug("Successfully completed request");
|
logger.debug("Successfully completed request");
|
||||||
this.asyncContext.complete();
|
this.asyncContext.complete();
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private ServletRequest getRequest() {
|
private void runIfAsyncNotComplete(Runnable task) {
|
||||||
ServletRequest request = null;
|
|
||||||
try {
|
try {
|
||||||
request = this.asyncContext.getRequest();
|
if (this.asyncContext.getRequest().isAsyncStarted()) {
|
||||||
} catch (IllegalStateException ignore) {
|
task.run();
|
||||||
// AsyncContext has been recycled and should not be used
|
}
|
||||||
|
}
|
||||||
|
catch (IllegalStateException ex) {
|
||||||
|
// Ignore:
|
||||||
|
// AsyncContext recycled and should not be used
|
||||||
|
// e.g. TIMEOUT_LISTENER (above) may have completed the AsyncContext
|
||||||
}
|
}
|
||||||
return request;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -180,13 +180,11 @@ public class ServletServerHttpResponse extends AbstractListenerServerHttpRespons
|
||||||
Throwable ex = event.getThrowable();
|
Throwable ex = event.getThrowable();
|
||||||
ex = (ex != null ? ex : new IllegalStateException("Async operation timeout."));
|
ex = (ex != null ? ex : new IllegalStateException("Async operation timeout."));
|
||||||
handleError(ex);
|
handleError(ex);
|
||||||
event.getAsyncContext().complete();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onError(AsyncEvent event) {
|
public void onError(AsyncEvent event) {
|
||||||
handleError(event.getThrowable());
|
handleError(event.getThrowable());
|
||||||
event.getAsyncContext().complete();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleError(Throwable ex) {
|
void handleError(Throwable ex) {
|
||||||
|
|
Loading…
Reference in New Issue