【问题标题】:Play Framework await() makes the application act wierdPlay Framework await() 使应用程序行为怪异
【发布时间】:2013-04-19 21:15:17
【问题描述】:

我在控制器的 await(Future future) 方法上遇到了一些奇怪的问题。

每当我在代码中的任何位置添加等待行时,一些与我放置等待的位置无关的通用模型开始加载不正确,我无法访问它们的任何属性。

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

【问题讨论】:

  • 你能展示你代码的相关部分吗?

标签: java asynchronous playframework-1.x


【解决方案1】:

当您在控制器中使用 await 时,它会增强字节码以将单个方法分成两个线程。这很酷,但绝对是 Play1 的“黑魔法”之一。但是,这是 Play 经常表现得很奇怪并且需要重新启动(或者如您所见,需要更改一些代码)的地方 - 另一个可能表现得很奇怪的地方是当您更改 Model 类时。

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

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

public static void computeSomething() { 承诺延迟结果 = veryLongComputation(…); 字符串结果 = 等待(延迟结果); 渲染(结果); }

实际上,您的代码将在 2 个步骤中以 2 个不同的线程执行。但如你所见,它非常 对您的应用程序代码透明。

使用 await(...) 和延续,您可以编写一个循环:

 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 只是一个 play Job 类,其中 doJobWithResult 被覆盖 - 所以它返回对象。有关工作的更多信息,请参阅http://www.playframework.com/documentation/1.2.5/jobs

调用 job.now() 返回一个未来/承诺,您可以像这样使用它:await(job.now())

【讨论】:

  • 太好了,我得出了同样的结论,我无法形容它比 play 的黑魔法更好。您的解决方法似乎很有趣,但是如果我在这里等待对象准备好,我该如何控制呢? await(1s) 直到 promiseObject.isDone?
  • 如果你想等待某些东西返回,那么使用 Job 和结果。我会更新答案。
  • 希望编辑有所帮助。但是这个问题的主要问题是在开发时如何进行自动重新编译。我会说,它只是有时会中断——知道什么/为什么会帮助你知道什么时候需要重新开始游戏。
  • 是的,那 await(promiseTaskResult); line 是搞乱我的项目的那个,所以我必须避免使用它。我最终使用了旧的、已弃用且不那么酷的 waitFor()。不过这确实对我有很大帮助,谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-12
  • 2019-09-29
  • 1970-01-01
  • 1970-01-01
  • 2018-12-14
相关资源
最近更新 更多