[英]Spring MVC asynchronous request timing out intermittently when DeferredResult passed to an Akka actor
I have implemented various Spring MVC REST endpoints to expose services that return a DeferredResult
which is handed off to an Akka TypedActor
to be completed. 我已经实现了各种Spring MVC REST端点,以公开返回
DeferredResult
服务,该服务将移交给Akka TypedActor
来完成。 The application is deployed into a Glassfish 4 server. 该应用程序已部署到Glassfish 4服务器中。
Generally the services execute and return as expected but I am intermittently receiving the following exception that occurs at the timeout interval I have specified: 通常,服务会按预期执行并返回,但是我间歇性地收到以下在我指定的超时间隔内发生的异常:
WARNING: Error invoking requestDestroyed method on ServletRequestListener org.jboss.weld.servlet.WeldListener
java.lang.NullPointerException
at org.jboss.weld.context.AbstractBoundContext.deactivate(AbstractBoundContext.java:71)
at org.jboss.weld.context.http.HttpRequestContextImpl.deactivate(HttpRequestContextImpl.java:70)
at org.jboss.weld.servlet.WeldListener.requestDestroyed(WeldListener.java:154)
at org.apache.catalina.core.StandardContext.fireRequestDestroyedEvent(StandardContext.java:5261)
at org.apache.catalina.core.StandardHostValve.postInvoke(StandardHostValve.java:255)
at org.apache.catalina.connector.Request.errorDispatchAndComplete(Request.java:4484)
at org.apache.catalina.connector.Request.asyncTimeout(Request.java:4424)
at org.apache.catalina.connector.Request.processTimeout(Request.java:4458)
at org.apache.catalina.connector.Request.access$000(Request.java:156)
at org.apache.catalina.connector.Request$6.onTimeout(Request.java:4302)
at org.glassfish.grizzly.http.server.Response$SuspendTimeout.onTimeout(Response.java:2024)
at org.glassfish.grizzly.http.server.Response$DelayQueueWorker.doWork(Response.java:2073)
at org.glassfish.grizzly.http.server.Response$DelayQueueWorker.doWork(Response.java:2068)
at org.glassfish.grizzly.utils.DelayedExecutor$DelayedRunnable.run(DelayedExecutor.java:158)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:724)
The servlet definition is my web.xml
is as follows: servlet的定义是我的
web.xml
如下:
<servlet>
<servlet-name>DispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value/>
</init-param>
<load-on-startup>1</load-on-startup>
<async-supported>true</async-supported>
</servlet>
An example of one of my Spring MVC endpoints is: 我的Spring MVC端点之一的示例是:
@RequestMapping(value = "/general", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE)
@ResponseStatus(HttpStatus.ACCEPTED)
public DeferredResult<String> processGeneralDocuments(@RequestBody DocumentsRequestBody requestBody) {
DeferredResult<String> result = new DeferredResult<>(appConfig.getDefaultRestTimeout());
documentsServiceBridge.general(result, requestBody.getDocuments());
return result;
}
The implementation for the general
method of the DocumentsStoreBridge
TypedActor
is as follows: DocumentsStoreBridge
TypedActor
的general
方法的实现如下:
@Override
public void general(DeferredResult<String> result, List<AbstractDocument> documents) {
LOG.debug("Processing {} general documents...", documents.size());
try {
result.setResult(documents.size() + " general documents accepted.");
LOG.debug("DeferredResult set");
for (AbstractDocument document : documents) {
documentStore.get().getActorRef().tell(document, TypedActor.context().self());
LOG.debug("{} document sent to {}", document.get_id(), documentStore.get().getActorType());
}
} catch (Exception e) {
result.setErrorResult(e);
}
}
As you can see in the DocumentsStoreBridge
implementation I am setting the result of the DeferredResult almost immediately, so would expect that to complete the asynchronous request. 如您在
DocumentsStoreBridge
实现中所看到的,我几乎立即设置DeferredResult的结果,因此希望可以完成异步请求。
What actually happens, intermittently, is that the result is set correctly, and the flow of my program continues, however the asynchronous request is not completed and therefore the client receives a HTTP 500 error when the request times out. 间歇性地实际发生的结果是正确设置了结果,并且我的程序继续进行,但是异步请求未完成,因此,请求超时时,客户端会收到HTTP 500错误。
Any help with this is greatly appreciated. 任何帮助,我们将不胜感激。
升级到GlassFish 4.1之后,此问题现在似乎已解决,我想与4.1打包在一起的WELD的较新版本已包含此修复程序。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.