Niedawno przeniosłem się do Play 2.0 i mam kilka pytań dotyczących tego, jak kontrolery rzeczywiście działają w grze.Jak dokładnie działają konsole Play 2.0/Async?
W play docs można wymienić:
Ze względu na sposób Zagraj 2.0 dzieła, kod działanie musi być tak szybko, jak to możliwe (czyli bez blokowania.).
Jednak w another part of the docs:
/actions {
router = round-robin
nr-of-instances = 24
}
i
actions-dispatcher = {
fork-join-executor {
parallelism-factor = 1.0
parallelism-max = 24
}
}
Wydaje się, że istnieje 24 aktorów dedykowanych kontrolerów obsługujących. Domyślam się, że każde żądanie przydziela jednego z tych aktorów na cały okres trwania wniosku. Czy to prawda?
Co ponadto oznacza parallelism-factor
i jak różni się fork-join-executor
od thread-pool
?
Również - docs powinni powiedzieć, że Async powinien być używany do długich obliczeń. Co kwalifikuje się jako długie obliczenie? 100ms? 300ms? 5 sekund? 10 sekund? Zgaduję, że to coś ponad sekundę, ale jak to ustalić?
Powodem tego pytania jest to, że testowanie połączeń kontrolera asynchronicznego jest o wiele trudniejsze niż zwykłe połączenia. Musisz uruchomić fałszywą aplikację i wykonać pełne żądanie, zamiast tylko wywoływać metodę i sprawdzać jej wartość zwracaną.
Nawet jeśli tak nie było, to wątpię, że zawijanie wszystkiego w Async
i Akka.future
jest drogą.
Poprosiłem o to w kanale IRC#playframework, ale nie było odpowiedzi i wydaje się, że nie jestem jedyną osobą, która nie jest pewna, jak należy postąpić.
Wystarczy powtórzyć:
- Czy to prawda, że każdy wniosek przydziela jednego aktora z/działań basenie?
- Co oznacza
parallelism-factor
i dlaczego jest to 1? - Czym różni się
fork-join-executor
odthread-pool-executor
? - Jak długo należy obliczać owijanie w
Async
? - Czy nie można przetestować metody kontrolera asynchronicznego bez tworzenia fałszywych aplikacji?
Z góry dziękuję.
Edycja: niektóre rzeczy z IRC
jakiś materiał z IRC.
<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 ;)
O punkcie 1. Jakie korzyści wysyłania zadań off do innych podmiotów, a nie tylko zwiększenie liczby wątków na/działań lubić 150 (dla 150 równoczesnych działań)? – arturaz
Pomyśl o tym w ten sposób. Masz na biurku setkę rzeczy do zrobienia. Który byłby bardziej wydajny? zdejmij jeden ze stosu, pracuj nad nim do końca, a następnie przejdź do następnego. Lub weź 150 pierwszych i pracuj na każdym z nich, dzieląc czas pomiędzy 150 różnych rzeczy. Pierwszy jest bardziej wydajny, ponieważ nie tracisz czasu na "przełączniki kontekstu". To samo dotyczy tutaj. – stew
Ale wysłanie zadania do innego aktora prowadzi również do przełączenia kontekstu. Jakie są korzyści? –