Scala Play framework 2.0控制器/异步究竟是如何工作的?
我最近转到了PlayFramework2.0,关于控制器在游戏中的实际工作方式,有一些问题与我有关 其中提到: 由于Play2.0的工作方式,动作代码必须尽可能快 可能(即非阻塞) 但在以下方面: 及 似乎有24个参与者分配给控制器处理。我猜每个请求都会在请求的生命周期中分配一个参与者是这样吗? 另外,Scala Play framework 2.0控制器/异步究竟是如何工作的?,scala,playframework-2.0,akka,evented-io,Scala,Playframework 2.0,Akka,Evented Io,我最近转到了PlayFramework2.0,关于控制器在游戏中的实际工作方式,有一些问题与我有关 其中提到: 由于Play2.0的工作方式,动作代码必须尽可能快 可能(即非阻塞) 但在以下方面: 及 似乎有24个参与者分配给控制器处理。我猜每个请求都会在请求的生命周期中分配一个参与者是这样吗? 另外,parallelism factor是什么意思,fork-join-executor与thread-pool有何不同 另外,文档应该说明异步应该用于长时间的计算什么算长?100毫秒?300毫秒?5
parallelism factor
是什么意思,fork-join-executor
与thread-pool
有何不同
另外,文档应该说明异步应该用于长时间的计算什么算长?100毫秒?300毫秒?5秒?10秒?我猜一秒钟内什么都可以,但如何确定呢
这个问题的原因是测试异步控制器调用比常规调用困难得多。您必须启动一个伪应用程序并执行一个完整的请求,而不是仅仅调用一个方法并检查其返回值
即使不是这样,我也怀疑用Async
和Akka.future
来包装一切是正确的做法
我在#playframework IRC频道上问过这个问题,但没有人回答,似乎我不是唯一一个不确定应该如何做的人
我只想重申:
fork join executor
与线程池executor
有何不同Async
中包装需要多长时间<imeredith> arturaz: i cant be boethered writing up a full reply but here are key points
<imeredith> arturaz: i believe that some type of CPS goes on with async stuff which frees up request threads
<arturaz> CPS?
<imeredith> continuations
<imeredith> when the future is finished, or timedout, it then resumes the request
<imeredith> and returns data
<imeredith> arturaz: as for testing, you can do .await on the future and it will block until the data is ready
<imeredith> (i believe)
<imeredith> arturaz: as for "long" and parallelism - the longer you hold a request thread, the more parrellism you need
<imeredith> arturaz: ie servlets typically need a lot of threads because you have to hold the request thread open for a longer time then if you are using play async
<imeredith> "Is it right that every request allocates one actor from /actions pool?" - yes i belive so
<imeredith> "What does parallelism-factor mean and why is it 1?" - im guessing this is how many actors there are in the pool?
<imeredith> or not
<imeredith> "How does fork-join-executor differ from thread-pool-executor?" -no idea
<imeredith> "How long should a calculation be to become wrapped in Async?" - i think that is the same as asking "how long is a piece of string"
<imeredith> "Is is not possible to test async controller method without spinning up fake applications?" i think you should be able to get the result
<viktorklang> imeredith: A good idea is to read the documentation: http://doc.akka.io/docs/akka/2.0.3/general/configuration.html ( which says parallelism-factor is: # Parallelism (threads) ... ceil(available processors * factor))
<arturaz> viktorklang, don't get me wrong, but that's the problem - this is not documentation, it's a reminder to yourself.
<arturaz> I have absolutely no idea what that should mean
<viktorklang> arturaz: It's the number of processors available multiplied with the factor you give, and then rounded up using "ceil". I don't know how it could be more clear.
<arturaz> viktorklang, how about: This factor is used in calculation `ceil(number of processors * factor)` which describes how big is a thread pool given for your actors.
<viktorklang> arturaz: But that is not strictly true since the size is also guarded by your min and max values
<arturaz> then why is it there? :)
<viktorklang> arturaz: Parallelism (threads) ... ceil(available processors * factor) could be expanded by adding a big of conversational fluff: Parallelism ( in other words: number of threads), it is calculated using the given factor as: ceil(available processors * factor)
<viktorklang> arturaz: Because your program might not work with a parallelism less than X and you don't want to use more threads than X (i.e if you have a 48 core box and you have 4.0 as factor that'll be a crapload of threads)
<viktorklang> arturaz: I.e. scheduling overhead gives diminishing returns, especially if ctz switching is across physical slots.
<viktorklang> arturaz: Changing thread pool sizes will always require you to have at least basic understanding on Threads and thread scheduling
<viktorklang> arturaz: makes sense?
<arturaz> yes
<arturaz> and thank you
<arturaz> I'll add this to my question, but this kind of knowledge would be awesome docs ;)
arturaz:我写不出一个完整的答复,但这里有几个要点
arturaz:我相信某种类型的CPS会继续使用异步的东西来释放请求线程
CPS?
延续
当future或timedout完成时,它会恢复请求
并返回数据
阿图拉兹:至于测试,你可以这样做。等待未来,它将阻止,直到数据准备就绪
(我相信)
arturaz:至于“长”和并行性——你持有请求线程的时间越长,你需要的并行性就越多
arturaz:ie Servlet通常需要很多线程,因为如果使用play async,则必须将请求线程保持在打开状态更长的时间
“每个请求从/actions池中分配一个参与者是否正确?”-是的,我相信是这样
“平行度因子是什么意思?为什么是1?”-我猜这就是池中有多少演员?
还是不
“fork join executor和线程池executor有何不同?”-不知道
“一个计算应该在异步中包装多长时间?”-我认为这与问“一段字符串有多长”是一样的
“在不旋转虚假应用程序的情况下测试异步控制器方法是不可能的吗?”我认为您应该能够得到结果
imeredith:一个好主意是阅读文档:http://doc.akka.io/docs/akka/2.0.3/general/configuration.html (表示并行度因子为:#并行度(线程)…ceil(可用处理器*因子))
viktorklang,别误会我的意思,但这就是问题所在——这不是文档,而是提醒你自己。
我完全不知道那意味着什么
arturaz:可用处理器的数量乘以你给出的因子,然后用“ceil”四舍五入。我不知道怎样才能更清楚。
viktorklang,怎么样:这个因子用于计算‘ceil(处理器数量*因子)’,它描述了为参与者提供的线程池有多大。
阿图拉兹:但这并不是严格正确的,因为大小也由最小值和最大值保护
那为什么会在那里呢?:)
arturaz:并行性(线程)。。。ceil(可用处理器*因子)可以通过添加大量会话绒毛来扩展:并行性(换句话说:线程数),它是使用给定的因子计算的:ceil(可用处理器*因子)
arturaz:因为您的程序可能无法使用小于X的并行度,并且您不希望使用比X更多的线程(即,如果您有一个48核的机箱,并且您有4.0作为因子,那么将是一个线程负载)
arturaz:也就是说,调度开销带来的回报是递减的,特别是当ctz切换跨越物理插槽时。
arturaz:更改线程池大小始终要求您至少对线程和线程调度有基本的了解
阿图拉兹:有道理吗?
对
谢谢你
我会在我的问题中添加这一点,但这种知识将非常棒;)
actions-dispatcher = {
fork-join-executor {
parallelism-factor = 1.0
parallelism-max = 24
}
}
<imeredith> arturaz: i cant be boethered writing up a full reply but here are key points
<imeredith> arturaz: i believe that some type of CPS goes on with async stuff which frees up request threads
<arturaz> CPS?
<imeredith> continuations
<imeredith> when the future is finished, or timedout, it then resumes the request
<imeredith> and returns data
<imeredith> arturaz: as for testing, you can do .await on the future and it will block until the data is ready
<imeredith> (i believe)
<imeredith> arturaz: as for "long" and parallelism - the longer you hold a request thread, the more parrellism you need
<imeredith> arturaz: ie servlets typically need a lot of threads because you have to hold the request thread open for a longer time then if you are using play async
<imeredith> "Is it right that every request allocates one actor from /actions pool?" - yes i belive so
<imeredith> "What does parallelism-factor mean and why is it 1?" - im guessing this is how many actors there are in the pool?
<imeredith> or not
<imeredith> "How does fork-join-executor differ from thread-pool-executor?" -no idea
<imeredith> "How long should a calculation be to become wrapped in Async?" - i think that is the same as asking "how long is a piece of string"
<imeredith> "Is is not possible to test async controller method without spinning up fake applications?" i think you should be able to get the result
<viktorklang> imeredith: A good idea is to read the documentation: http://doc.akka.io/docs/akka/2.0.3/general/configuration.html ( which says parallelism-factor is: # Parallelism (threads) ... ceil(available processors * factor))
<arturaz> viktorklang, don't get me wrong, but that's the problem - this is not documentation, it's a reminder to yourself.
<arturaz> I have absolutely no idea what that should mean
<viktorklang> arturaz: It's the number of processors available multiplied with the factor you give, and then rounded up using "ceil". I don't know how it could be more clear.
<arturaz> viktorklang, how about: This factor is used in calculation `ceil(number of processors * factor)` which describes how big is a thread pool given for your actors.
<viktorklang> arturaz: But that is not strictly true since the size is also guarded by your min and max values
<arturaz> then why is it there? :)
<viktorklang> arturaz: Parallelism (threads) ... ceil(available processors * factor) could be expanded by adding a big of conversational fluff: Parallelism ( in other words: number of threads), it is calculated using the given factor as: ceil(available processors * factor)
<viktorklang> arturaz: Because your program might not work with a parallelism less than X and you don't want to use more threads than X (i.e if you have a 48 core box and you have 4.0 as factor that'll be a crapload of threads)
<viktorklang> arturaz: I.e. scheduling overhead gives diminishing returns, especially if ctz switching is across physical slots.
<viktorklang> arturaz: Changing thread pool sizes will always require you to have at least basic understanding on Threads and thread scheduling
<viktorklang> arturaz: makes sense?
<arturaz> yes
<arturaz> and thank you
<arturaz> I'll add this to my question, but this kind of knowledge would be awesome docs ;)
object ControllerHelpers {
class ResultExtensions(result: Result) {
/**
* Retrieve Promise[Result] from AsyncResult
* @return
*/
def asyncResult = result match {
case async: AsyncResult => async.result
case _ => throw new IllegalArgumentException(
"%s of type %s is not AsyncResult!".format(result, result.getClass)
)
}
/**
* Block until result is available.
*
* @return
*/
def await = asyncResult.await
/**
* Block until result is available.
*
* @param timeout
* @return
*/
def await(timeout: Long) = asyncResult.await(timeout)
/**
* Block for max 5 seconds to retrieve result.
* @return
*/
def get = await.get
}
}
implicit def extendResult(result: Result) =
new ControllerHelpers.ResultExtensions(result)
val result = c.postcodeTimesCsv()(request(params)).get
status(result) should be === OK