问题
When using phantom how dangerous is it to be following this pattern in db calls:
Await.result(dbOperationFut, 30.seconds)
This isn't really phantom specific but it is the scala driver being used.
I am weary of this pattern because of the potential GC pause that might last for over x seconds. How many seconds is safe given GC pauses?
I am personally in favor of using for-comp and not blocking like this, but just want to know if this is a REALLY bad practice or it is fine.
Context: This would be for akka based applications (akka, akka http)
Thoughts?
回答1:
Becareful with Await.result
Note this applies for both Akka and play apps
Await.result
should be used very carefully only when it is absolutely necessary.
Await.result
blocks the thread in which it is running until the given duration. Blocking the thread will waste the precious computation resource because that thread will not be able to do any useful computation like handling the new request or number crunching in an algorithm etc.
So, Avoid using the Await.result
as much as possible.
But, when do we use it (Await.result) ?
Here is one of the typical use case for using Await.result
.
Lets say you have written a program containing main thread and all the computation inside the main thread is asynchronous. Now once you start the asynchronous computation inside the main thread. Some one has to stop the main thread from existing till the asynchronous computation finishes, if not the program stops running and you cannot see the result of the asynchronous computation.
When an application begins running, there is one non-daemon thread, whose job is to execute main(). JVM will not exit by itself until and unless non-daemon threads are completed.
object Main {
def main(args: Array[String]): Unit = {
import scala.concurrent.Future
import scala.concurrent.duration._
val f = Future { //do something }
//stop main thread till f completes
Await.result(f, 10 seconds)
}
}
Future uses daemon threads for running. So daemon threads cannot stop the JVM from shutting down. So JVM shuts down even if non-daemon threads are running.
In the above case there is no other way expect stopping (blocking) the main thread till the computation f
completes if not main thread exits and computation stops.
In most of the cases you do not need to use
Await.result
and simpleFuture
composition usingmap
andflatMap
would suffice.
Risks of using Await.result (In general all blocking code)
Running out of threads in event based model
In event based model you will quickly run out of threads if you have blocking code which takes long time to return. In playframework any blocking call could decrease the performance of the application and app will becomes dead slow as it runs out of threads.
Running out of memory in non-event based models
In thread per request models. When you have blocking calls which take long time to exit/return.
case 1: If you have fixed thread pool then application might run out of threads.
case 2: If you have dynamically growing thread pool then your application will suffer from too much context switching overhead and also will run out of memory because of too many blocked threads in memory.
In all of the cases no useful work is done expect for waiting for some IO or some other event.
来源:https://stackoverflow.com/questions/40795109/how-risky-is-it-to-call-await-result-on-db-calls