Play Framework await()使应用程序行为怪异

时间:2013-04-19 21:15:17

标签: java asynchronous playframework-1.x

我遇到一些奇怪的问题,方法是等待(未来的未来)控制器。

每当我在代码中的任何地方添加await行时,一些GenericModel与我放置的位置无关,开始加载错误,我无法访问它们的任何属性。

最奇怪的是,如果我在项目的任何地方更改另一个完全不同的java文件中的某些内容,我会尝试重新编译,并且在那一刻它开始完美运行,直到我再次清理tmp。

1 个答案:

答案 0 :(得分:1)

当你在控制器中使用await时,它会进行字节码增强,将单个方法分解为两个线程。这很酷,但绝对是Play1的“黑魔法”技巧之一。但是,这是一个Play常常很奇怪并且需要重启的地方(或者你发现,一些代码在变化) - 另一个地方就是你可以改变一个Model类。

http://www.playframework.com/documentation/1.2.5/asynchronous#SuspendingHTTPrequests

  

为了更容易处理我们引入的异步代码   延续。 Continuations允许您的代码被暂停   恢复透明。因此,您必须编写代码   方式,如:

     

public static void computeSomething(){        承诺delayedResult = veryLongComputation(...);        String result = await(delayedResult);        渲染(结果); }

     

实际上,您的代码将分两步执行,分为2个不同的hread。但正如你所看到的那样,它是非常的   透明的应用程序代码。

     

使用await(...)和continuation,你可以写一个循环:

 public static void loopWithoutBlocking() {
     for(int i=0; i<=10; i++) { 
          Logger.info(i);
          await("1s");
     }
     renderText("Loop finished"); } 
  

只使用1个线程(这是开发模式中的默认值)来处理请求,Play能够   同时为多个请求同时运行这些循环。


回复您的评论:

 public static void generatePDF(Long reportId) {
    Promise<InputStream> pdf = new ReportAsPDFJob(report).now();
    InputStream pdfStream = await(pdf);
    renderBinary(pdfStream);

和ReportAsPDFJob只是一个重写了doJobWithResult的播放Job类 - 所以它返回对象。有关工作的更多信息,请参阅http://www.playframework.com/documentation/1.2.5/jobs

致电job.now()会返回未来/承诺,您可以这样使用:await(job.now())