简体   繁体   English

当DeferredResult传递给Akka actor时,Spring MVC异步请求间歇性地超时

[英]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 TypedActorgeneral方法的实现如下:

@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.

相关问题 具有DeferredResult和Reactor的Spring异步REST - Spring Asynchronous REST with DeferredResult and Reactor 在Spring MVC中使用DeferredResult和RxJava时的性能降低 - Performance reduction when using DeferredResult and RxJava with Spring MVC 如何使用 AKKA/Actor 进行异步/同步调用 - How to use AKKA/Actor for asynchronous/synchronous calls Spring MVC InterceptorHandler 使用 DeferredResult 调用了两次 - Spring MVC InterceptorHandler called twice with DeferredResult spring mvc:DeferredResult 和 ListenableFuture 的区别? - spring mvc: the difference between DeferredResult and ListenableFuture? 可以在Spring MVC 4中将DeferredResult与@ModelAttribute一起使用吗? - Can DeferredResult be used together with @ModelAttribute in Spring MVC 4? 如何将Spring MVC的延迟结果发送回客户端(角度js) - How deferredresult of Spring MVC is sent back to client(angular js) 用于DeferredResult的Spring MVC单元测试不会调用超时回调 - Spring MVC unit test for DeferredResult doesn't call timeout callback 用UUID命名时,为akka actor定义调度程序 - defining dispatcher for akka actor when named with UUID Spring 3 DataSourceTransactionManager在与MySQL进行交易时偶尔会超时 - Spring 3 DataSourceTransactionManager sporadically timing out when getting transaction to MySQL
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM