Supplier for timeout result in DeferredResult

Issue: SPR-17364
This commit is contained in:
陈灵敏 2018-10-11 14:01:40 +08:00 committed by Rossen Stoyanchev
parent 8df0bc88d2
commit 4ee704cedf
1 changed files with 22 additions and 8 deletions

View File

@ -19,6 +19,8 @@ package org.springframework.web.context.request.async;
import java.util.PriorityQueue; import java.util.PriorityQueue;
import java.util.concurrent.Callable; import java.util.concurrent.Callable;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.function.Supplier;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
@ -60,7 +62,7 @@ public class DeferredResult<T> {
@Nullable @Nullable
private final Long timeout; private final Long timeout;
private final Object timeoutResult; private final Supplier<?> timeoutResult;
private Runnable timeoutCallback; private Runnable timeoutCallback;
@ -79,18 +81,18 @@ public class DeferredResult<T> {
* Create a DeferredResult. * Create a DeferredResult.
*/ */
public DeferredResult() { public DeferredResult() {
this(null, RESULT_NONE); this(null, () -> RESULT_NONE);
} }
/** /**
* Create a DeferredResult with a timeout value. * Create a DeferredResult with a custom timeout value.
* <p>By default not set in which case the default configured in the MVC * <p>By default not set in which case the default configured in the MVC
* Java Config or the MVC namespace is used, or if that's not set, then the * Java Config or the MVC namespace is used, or if that's not set, then the
* timeout depends on the default of the underlying server. * timeout depends on the default of the underlying server.
* @param timeout timeout value in milliseconds * @param timeout timeout value in milliseconds
*/ */
public DeferredResult(Long timeout) { public DeferredResult(Long timeout) {
this(timeout, RESULT_NONE); this(timeout, () -> RESULT_NONE);
} }
/** /**
@ -99,11 +101,22 @@ public class DeferredResult<T> {
* @param timeout timeout value in milliseconds (ignored if {@code null}) * @param timeout timeout value in milliseconds (ignored if {@code null})
* @param timeoutResult the result to use * @param timeoutResult the result to use
*/ */
public DeferredResult(@Nullable Long timeout, Object timeoutResult) { public DeferredResult(@Nullable Long timeout, final Object timeoutResult) {
this.timeoutResult = timeoutResult; this.timeoutResult = () -> timeoutResult;
this.timeout = timeout; this.timeout = timeout;
} }
/**
* Variant of {@link #DeferredResult(Long, Object)} that accepts a dynamic
* fallback value based on a {@link Supplier}.
* @param timeout timeout value in milliseconds (ignored if {@code null})
* @param timeoutResult the result supplier to use
* @since 5.1.1
*/
public DeferredResult(@Nullable Long timeout, Supplier<?> timeoutResult) {
this.timeoutResult = timeoutResult;
this.timeout = timeout;
}
/** /**
* Return {@code true} if this DeferredResult is no longer usable either * Return {@code true} if this DeferredResult is no longer usable either
@ -281,10 +294,11 @@ public class DeferredResult<T> {
} }
} }
finally { finally {
if (timeoutResult != RESULT_NONE) { Object value = timeoutResult.get();
if (value != RESULT_NONE) {
continueProcessing = false; continueProcessing = false;
try { try {
setResultInternal(timeoutResult); setResultInternal(value);
} }
catch (Throwable ex) { catch (Throwable ex) {
logger.debug("Failed to handle timeout result", ex); logger.debug("Failed to handle timeout result", ex);