我有点困惑.
从文档:
播放默认线程池 - 这是默认线程池,其中执行Play Framework中的所有应用程序代码,不包括一些迭代代码.它是Akka调度程序,可以通过配置Akka进行配置,如下所述.默认情况下,每个处理器有一个线程.
是否造福包裹在阻塞数据库调用Future,在调用Future本身被由包裹async控制器(它返回),为了让默认线程池处理其他用户的请求?
它只是将阻塞代码移动到另一个线程(来自专用的ExecutionContext)中,但保留Action未阻塞.
我遇到过这篇文章,但我对给出的答案并不满意.
实际上,如果我让数据库在默认线程池中调用阻塞,那么在此期间它是否可能阻止处理不依赖于数据库的其他用户请求?
注意:我的数据库(Neo4j)没有异步驱动程序.
asynchronous scala nonblocking playframework playframework-2.3
该播放2.2文档指出:
由于Play的工作方式,动作代码必须尽可能快(即非阻塞).那么如果我们还不能生成它,我们应该返回什么呢?回应是未来的结果!
未来[结果]最终将使用Result类型的值进行兑换.通过给出Future [Result]而不是普通Result,我们可以快速生成结果而不会阻塞.然后,Play将在兑换承诺后立即提供此结果.
在等待响应时将阻止Web客户端,但服务器上不会阻止任何内容,并且可以使用服务器资源为其他客户端提供服务.
创建返回Future的操作,Action.async而不是Action.apply正常的非异步操作.
有非异步操作有什么好处吗?令我感到震惊的是,确保我的所有动作都不会阻止的最佳方法是声明所有动作都使用Action.async.
实际上,根据Play Framework 2.3文档,它在Play 2.3中看起来像所有操作都是异步的:
注意:Action.apply和Action.async都创建以相同方式在内部处理的Action对象.有一种Action是异步的,而不是两种(同步的和异步的)..async构建器只是简化基于返回Future的API创建操作的工具,这使得编写非阻塞代码变得更加容易.
我试图从概念上理解为什么在Play Framework 2.0中,它被认为是调用WS.url().get()Web服务调用的最佳实践,但如果你在promise中包装任何其他阻塞调用(如JDBC调用),建议你在除默认执行上下文之外的执行上下文?
据我所知,默认情况下,Play Framework的线程池配置为每个核心有一个线程,每个控制器都希望运行完全非阻塞的代码.因此,如果您在控制器(例如,Web服务)中进行阻止调用,那么您需要确保此调用不会阻止可用于控制器的线程.
否则,将不会有任何线程执行控制器,因为它们都处于阻塞状态.
但令我困惑的是以下几点:
WS.url().get()也在默认执行上下文中执行,另一方面,线程池配置上的Play框架文档声明"请注意,您可能想要...将您的阻止代码包装在Futures中这不会使它成为非阻塞,它只是意味着阻塞将在不同的线程中发生."上述不是指WS.url().get()在同一默认执行上下文中"只是在不同的线程中发生"吗?在不同的执行上下文中执行JDBC调用有什么不同?