簡體   English   中英

當DeferredResult傳遞給Akka actor時,Spring MVC異步請求間歇性地超時

[英]Spring MVC asynchronous request timing out intermittently when DeferredResult passed to an Akka actor

我已經實現了各種Spring MVC REST端點,以公開返回DeferredResult服務,該服務將移交給Akka TypedActor來完成。 該應用程序已部署到Glassfish 4服務器中。

通常,服務會按預期執行並返回,但是我間歇性地收到以下在我指定的超時間隔內發生的異常:

    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)

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>

我的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;

}

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);
    }

}

如您在DocumentsStoreBridge實現中所看到的,我幾乎立即設置DeferredResult的結果,因此希望可以完成異步請求。

間歇性地實際發生的結果是正確設置了結果,並且我的程序繼續進行,但是異步請求未完成,因此,請求超時時,客戶端會收到HTTP 500錯誤。

任何幫助,我們將不勝感激。

升級到GlassFish 4.1之后,此問題現在似乎已解決,我想與4.1打包在一起的WELD的較新版本已包含此修復程序。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM