我一直在学习游戏,而且我已经掌握了大部分主要概念,但我正在努力应对平台为实现所有这些目标而采取的行动。
特别是,假设我有一个控制器,它会做一些耗费时间的事情。现在我明白了using Futures and asynchronous processing我怎么能让这些东西看起来不会阻塞,但如果它是资源密集型的东西,当然最终它必须阻止某处。根据文件:
通过将同步IO包装在Future中,您无法神奇地将同步IO变为异步。如果您无法更改应用程序的体系结构以避免阻塞操作,那么在某些时候必须执行操作,并且该线程将阻塞。因此,除了将操作封装在Future中之外,还需要将其配置为在单独的执行上下文中运行,该上下文已配置了足够的线程来处理预期的并发。
这一点我不明白:如果我通过Future
做的某些任务可能在一个单独的线程池中处理,那么Scala / Play在框架中如何/有什么魔力来协调这些线程使得无论哪个线程正在侦听HTTP套接字块足够长时间来执行所有复杂处理(数据库加载,序列化为JSON等等) - 在单独的线程中,然而以某种方式返回到原始阻塞线程必须向客户发回一些请求?
答案 0 :(得分:2)
免责声明:对于一般问题,这是一个简化的答案,我不想通过进入Play和Akka内部来使这更复杂。
一种方法是让线程监听套接字,但不写入它,让我们称之为A
。 A
跨越Future
,其本身包含计算所需的所有数据。重要的是不要将执行处理的线程与正在处理的数据混淆,因为数据(内存)由所有线程共享(有时需要显式同步)。未来将由({最终)线程B
处理。
现在,在A
完成之前,我是否需要B
阻止?它可以(并且在许多一般情况下可能是正确的解决方案),但在这种情况下,我们几乎不想停止收听我们的套接字。所以不,我们不会,A
忘记信息的一切,继续它的生命。
因此,当B
完成时,可能会映射Future或者有一个发送正确响应的侦听器。 B
本身可以根据原始邮件中的信息发送它!您只需要小心同步对套接字的访问,以避免与可能已经并行处理前一个或后一个消息的可能线程C
发生冲突。
你不能通过包装神奇地将同步IO变成异步 它在未来。如果您无法将应用程序的体系结构更改为 避免阻止操作
在许多(大多数?)情况下,应用程序架构的这种变化当然是可能的,当然也是在Play内部完成的。