Browse Source

Consistent result synchronization in WebAsyncManager

Issue: SPR-16571
pull/1739/head
Juergen Hoeller 7 years ago
parent
commit
cf74b1b8be
  1. 32
      spring-web/src/main/java/org/springframework/web/context/request/async/WebAsyncManager.java

32
spring-web/src/main/java/org/springframework/web/context/request/async/WebAsyncManager.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2017 the original author or authors.
* Copyright 2002-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -51,6 +51,7 @@ import org.springframework.web.util.UrlPathHelper; @@ -51,6 +51,7 @@ import org.springframework.web.util.UrlPathHelper;
* detected via {@link #hasConcurrentResult()}.
*
* @author Rossen Stoyanchev
* @author Juergen Hoeller
* @since 3.2
* @see org.springframework.web.context.request.AsyncWebRequestInterceptor
* @see org.springframework.web.servlet.AsyncHandlerInterceptor
@ -76,15 +77,13 @@ public final class WebAsyncManager { @@ -76,15 +77,13 @@ public final class WebAsyncManager {
private AsyncTaskExecutor taskExecutor = new SimpleAsyncTaskExecutor(this.getClass().getSimpleName());
private Object concurrentResult = RESULT_NONE;
private volatile Object concurrentResult = RESULT_NONE;
private Object[] concurrentResultContext;
private volatile Object[] concurrentResultContext;
private final Map<Object, CallableProcessingInterceptor> callableInterceptors =
new LinkedHashMap<>();
private final Map<Object, CallableProcessingInterceptor> callableInterceptors = new LinkedHashMap<>();
private final Map<Object, DeferredResultProcessingInterceptor> deferredResultInterceptors =
new LinkedHashMap<>();
private final Map<Object, DeferredResultProcessingInterceptor> deferredResultInterceptors = new LinkedHashMap<>();
/**
@ -105,7 +104,7 @@ public final class WebAsyncManager { @@ -105,7 +104,7 @@ public final class WebAsyncManager {
* {@code true}.
* @param asyncWebRequest the web request to use
*/
public void setAsyncWebRequest(final AsyncWebRequest asyncWebRequest) {
public void setAsyncWebRequest(AsyncWebRequest asyncWebRequest) {
Assert.notNull(asyncWebRequest, "AsyncWebRequest must not be null");
this.asyncWebRequest = asyncWebRequest;
this.asyncWebRequest.addCompletionHandler(() -> asyncWebRequest.removeAttribute(
@ -130,7 +129,7 @@ public final class WebAsyncManager { @@ -130,7 +129,7 @@ public final class WebAsyncManager {
* processing of the concurrent result.
*/
public boolean isConcurrentHandlingStarted() {
return ((this.asyncWebRequest != null) && this.asyncWebRequest.isAsyncStarted());
return (this.asyncWebRequest != null && this.asyncWebRequest.isAsyncStarted());
}
/**
@ -232,8 +231,10 @@ public final class WebAsyncManager { @@ -232,8 +231,10 @@ public final class WebAsyncManager {
* {@linkplain #getConcurrentResultContext() concurrentResultContext}.
*/
public void clearConcurrentResult() {
this.concurrentResult = RESULT_NONE;
this.concurrentResultContext = null;
synchronized (WebAsyncManager.this) {
this.concurrentResult = RESULT_NONE;
this.concurrentResultContext = null;
}
}
/**
@ -334,7 +335,7 @@ public final class WebAsyncManager { @@ -334,7 +335,7 @@ public final class WebAsyncManager {
private void setConcurrentResultAndDispatch(Object result) {
synchronized (WebAsyncManager.this) {
if (hasConcurrentResult()) {
if (this.concurrentResult != RESULT_NONE) {
return;
}
this.concurrentResult = result;
@ -349,7 +350,6 @@ public final class WebAsyncManager { @@ -349,7 +350,6 @@ public final class WebAsyncManager {
logger.debug("Concurrent result value [" + this.concurrentResult +
"] - dispatching request to resume processing");
}
this.asyncWebRequest.dispatch();
}
@ -425,8 +425,10 @@ public final class WebAsyncManager { @@ -425,8 +425,10 @@ public final class WebAsyncManager {
}
private void startAsyncProcessing(Object[] processingContext) {
clearConcurrentResult();
this.concurrentResultContext = processingContext;
synchronized (WebAsyncManager.this) {
this.concurrentResult = RESULT_NONE;
this.concurrentResultContext = processingContext;
}
this.asyncWebRequest.startAsync();
if (logger.isDebugEnabled()) {

Loading…
Cancel
Save