长计算AJAX导致重复控制器Play Framework控制器动作调用

时间:2014-01-28 13:05:28

标签: ajax playframework playframework-2.0

基本问题: 如果我对一个执行长计算(60秒或更长时间)的控制器方法进行AJAX调用,我会得到一个复制的线程进入并遵循相同的执行路径(尽管我可以从堆栈跟踪转储中得知 - 并且只有一个,这不会继续发生在第二个线程中)。这似乎只有在通过AJAX调用控制器操作时才会发生。这可以通过创建一个虚拟控制器方法来轻松复制,该方法在完成时返回的Thread.sleep()调用中没有任何内容。

我已经在一个没有AJAX调用的情况下加载的方法中对此进行了测试,并且它不会产生流氓线程。我尝试了各种形式的AJAX调用(几种形式的jQuery方法和基本JavaScript)并且每种方法得到了相同的结果。我最初认为它可能是一个线程问题所以我使用Promise(s)(http://www.playframework.com/documentation/2.1.x/JavaAsynchttp://www.playframework.com/documentation/2.1.x/JavaAkka)和AsyncResult实现了虚拟方法,但它没有效果。

我知道这两个线程正在使用相同的执行上下文。这是导致问题吗?将长计算移动到另一个上下文是否可以避免?关于第二个重复线程来自何处的任何想法?

控制器方法(长计算):

public static Result test()
{
    Logger.debug("*** TEST Controller entry: threadId=" + Thread.currentThread().getId());
    StackTraceElement[] stack = Thread.currentThread().getStackTrace();
    for(StackTraceElement e : stack)
    {
        Logger.debug("***" + e.toString());
    }

    Promise<Void> promiseString = Akka.future(
            new Callable<Void>() {
                public Void call() {
                    try
                    {
                        Logger.debug("*** going to sleep: threadId=" + Thread.currentThread().getId());
                        Thread.sleep(90000);
                    }
                    catch(InterruptedException e)
                    {
                        //swallow it whole and move on
                    }

                    return null;
                }
            }
    );

    Promise<Result> promiseResult = promiseString.map(
            new Function<Void, Result>() {
                public Result apply(Void voidParam) {
                    return ok("done");
                }
            }
    );

    return async(promiseResult);
}

0 个答案:

没有答案