Play Framework await() 使应用程序行为怪异
Posted
技术标签:
【中文标题】Play Framework await() 使应用程序行为怪异【英文标题】:Play Framework await() makes the application act wierd 【发布时间】:2013-04-19 21:15:17 【问题描述】:我在控制器的 await(Future future) 方法上遇到了一些奇怪的问题。
每当我在代码中的任何位置添加等待行时,一些与我放置等待的位置无关的通用模型开始加载不正确,我无法访问它们的任何属性。
最奇怪的是,如果我在项目的任何地方更改另一个完全不同的 java 文件中的某些内容,我猜 play 会尝试重新编译,并且在那一刻它开始完美运行,直到我再次清理 tmp。
【问题讨论】:
你能展示你代码的相关部分吗? 【参考方案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()。不过这确实对我有很大帮助,谢谢。以上是关于Play Framework await() 使应用程序行为怪异的主要内容,如果未能解决你的问题,请参考以下文章
Play Framework:如何不查看文件夹以了解 Play Framework 中的更改
如何构建版本独立的 Play!Framework 2 模块?