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