Fix timing issue with obtaining async result
Issue: SPR-11516
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2012 the original author or authors.
|
* Copyright 2002-2014 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -36,6 +36,9 @@ import org.springframework.web.servlet.support.RequestContextUtils;
|
|||||||
*/
|
*/
|
||||||
class DefaultMvcResult implements MvcResult {
|
class DefaultMvcResult implements MvcResult {
|
||||||
|
|
||||||
|
private static final Object RESULT_NONE = new Object();
|
||||||
|
|
||||||
|
|
||||||
private final MockHttpServletRequest mockRequest;
|
private final MockHttpServletRequest mockRequest;
|
||||||
|
|
||||||
private final MockHttpServletResponse mockResponse;
|
private final MockHttpServletResponse mockResponse;
|
||||||
@@ -48,7 +51,7 @@ class DefaultMvcResult implements MvcResult {
|
|||||||
|
|
||||||
private Exception resolvedException;
|
private Exception resolvedException;
|
||||||
|
|
||||||
private Object asyncResult;
|
private Object asyncResult = RESULT_NONE;
|
||||||
|
|
||||||
private CountDownLatch asyncResultLatch;
|
private CountDownLatch asyncResultLatch;
|
||||||
|
|
||||||
@@ -123,18 +126,18 @@ class DefaultMvcResult implements MvcResult {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object getAsyncResult(long timeout) {
|
public Object getAsyncResult(long timeout) {
|
||||||
// MockHttpServletRequest type doesn't have async methods
|
if (this.asyncResult == RESULT_NONE) {
|
||||||
HttpServletRequest request = this.mockRequest;
|
if ((timeout != 0) && this.mockRequest.isAsyncStarted()) {
|
||||||
if ((timeout != 0) && request.isAsyncStarted()) {
|
if (timeout == -1) {
|
||||||
if (timeout == -1) {
|
timeout = this.mockRequest.getAsyncContext().getTimeout();
|
||||||
timeout = request.getAsyncContext().getTimeout();
|
}
|
||||||
}
|
if (!awaitAsyncResult(timeout) && this.asyncResult == RESULT_NONE) {
|
||||||
if (!awaitAsyncResult(timeout)) {
|
throw new IllegalStateException(
|
||||||
throw new IllegalStateException(
|
"Gave up waiting on async result from handler [" + this.handler + "] to complete");
|
||||||
"Gave up waiting on async result from handler [" + this.handler + "] to complete");
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return this.asyncResult;
|
return (this.asyncResult == RESULT_NONE ? null : this.asyncResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean awaitAsyncResult(long timeout) {
|
private boolean awaitAsyncResult(long timeout) {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2012 the original author or authors.
|
* Copyright 2002-2014 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -89,6 +89,20 @@ public class AsyncTests {
|
|||||||
.andExpect(content().string("{\"name\":\"Joe\",\"someDouble\":0.0,\"someBoolean\":false}"));
|
.andExpect(content().string("{\"name\":\"Joe\",\"someDouble\":0.0,\"someBoolean\":false}"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Ignore
|
||||||
|
public void testDeferredResultWithSetValue() throws Exception {
|
||||||
|
MvcResult mvcResult = this.mockMvc.perform(get("/1").param("deferredResultWithSetValue", "true"))
|
||||||
|
.andExpect(request().asyncStarted())
|
||||||
|
.andExpect(request().asyncResult(new Person("Joe")))
|
||||||
|
.andReturn();
|
||||||
|
|
||||||
|
this.mockMvc.perform(asyncDispatch(mvcResult))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
|
||||||
|
.andExpect(content().string("{\"name\":\"Joe\",\"someDouble\":0.0,\"someBoolean\":false}"));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Controller
|
@Controller
|
||||||
private static class AsyncController {
|
private static class AsyncController {
|
||||||
@@ -115,6 +129,14 @@ public class AsyncTests {
|
|||||||
return deferredResult;
|
return deferredResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@RequestMapping(value="/{id}", params="deferredResultWithSetValue", produces="application/json")
|
||||||
|
@ResponseBody
|
||||||
|
public DeferredResult<Person> getDeferredResultWithSetValue() {
|
||||||
|
DeferredResult<Person> deferredResult = new DeferredResult<Person>();
|
||||||
|
deferredResult.setResult(new Person("Joe"));
|
||||||
|
return deferredResult;
|
||||||
|
}
|
||||||
|
|
||||||
public void onMessage(String name) {
|
public void onMessage(String name) {
|
||||||
for (DeferredResult<Person> deferredResult : this.deferredResults) {
|
for (DeferredResult<Person> deferredResult : this.deferredResults) {
|
||||||
deferredResult.setResult(new Person(name));
|
deferredResult.setResult(new Person(name));
|
||||||
|
|||||||
Reference in New Issue
Block a user