在数据库调用中调用 Await.result 的风险有多大
How risky is it to call Await.result on db calls
使用 phantom 时,在数据库调用中遵循此模式有多危险:
Await.result(dbOperationFut, 30.seconds)
这并不是真正的 phantom 特定,而是正在使用的 scala 驱动程序。
我厌倦了这种模式,因为潜在的 GC 暂停可能会持续超过 x 秒。给定 GC 暂停多少秒是安全的?
我个人赞成使用 for-comp 而不是像这样阻塞,但只是想知道这是一个非常糟糕的做法还是没问题。
上下文:这适用于基于 akka 的应用程序(akka、akka http)
想法?
注意Await.result
注意这适用于 Akka 和 play 应用程序
Await.result
should be used very carefully only when it is absolutely necessary.
Await.result
阻塞它所在的线程 运行ning 直到给定的持续时间。阻塞线程将浪费宝贵的计算资源,因为该线程将无法进行任何有用的计算,例如处理新请求或算法中的数字 c运行ching 等
因此,请尽可能避免使用 Await.result
。
But, when do we use it (Await.result) ?
这是使用 Await.result
的典型用例之一。
假设您编写了一个包含主线程的程序,并且主线程内的所有计算都是异步的。现在,一旦您在主线程内开始异步计算。有些人必须停止主线程的存在,直到异步计算完成,否则程序停止 运行ning 并且您看不到异步计算的结果。
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.
在上述情况下,如果主线程不退出且计算停止,则没有其他方法可以停止(阻塞)主线程直到计算 f
完成。
In most of the cases you do not need to use Await.result
and simple Future
composition using map
and flatMap
would suffice.
使用的风险Await.result(一般都是阻塞代码)
Running out of threads in event based model
在基于事件的模型中,如果您的阻塞代码需要很长时间 return,您将很快 运行 超出线程。在 playframework 中,任何阻塞调用都可能降低应用程序的性能,并且应用程序将变得非常慢,因为它 运行 没有线程。
Running out of memory in non-event based models
在每个请求模型的线程中。当您有需要很长时间才能到达 exit/return 的阻塞呼叫时。
情况 1:如果您有固定的线程池,那么应用程序可能 运行 线程不足。
情况 2:如果您有动态增长的线程池,那么您的应用程序将遭受过多的上下文切换开销,并且还会 运行 由于内存中阻塞的线程过多而导致内存不足.
在所有情况下,除了等待某些 IO 或其他事件外,没有完成任何有用的工作。
使用 phantom 时,在数据库调用中遵循此模式有多危险:
Await.result(dbOperationFut, 30.seconds)
这并不是真正的 phantom 特定,而是正在使用的 scala 驱动程序。
我厌倦了这种模式,因为潜在的 GC 暂停可能会持续超过 x 秒。给定 GC 暂停多少秒是安全的?
我个人赞成使用 for-comp 而不是像这样阻塞,但只是想知道这是一个非常糟糕的做法还是没问题。
上下文:这适用于基于 akka 的应用程序(akka、akka http)
想法?
注意Await.result
注意这适用于 Akka 和 play 应用程序
Await.result
should be used very carefully only when it is absolutely necessary.
Await.result
阻塞它所在的线程 运行ning 直到给定的持续时间。阻塞线程将浪费宝贵的计算资源,因为该线程将无法进行任何有用的计算,例如处理新请求或算法中的数字 c运行ching 等
因此,请尽可能避免使用 Await.result
。
But, when do we use it (Await.result) ?
这是使用 Await.result
的典型用例之一。
假设您编写了一个包含主线程的程序,并且主线程内的所有计算都是异步的。现在,一旦您在主线程内开始异步计算。有些人必须停止主线程的存在,直到异步计算完成,否则程序停止 运行ning 并且您看不到异步计算的结果。
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.
在上述情况下,如果主线程不退出且计算停止,则没有其他方法可以停止(阻塞)主线程直到计算 f
完成。
In most of the cases you do not need to use
Await.result
and simpleFuture
composition usingmap
andflatMap
would suffice.
使用的风险Await.result(一般都是阻塞代码)
Running out of threads in event based model
在基于事件的模型中,如果您的阻塞代码需要很长时间 return,您将很快 运行 超出线程。在 playframework 中,任何阻塞调用都可能降低应用程序的性能,并且应用程序将变得非常慢,因为它 运行 没有线程。
Running out of memory in non-event based models
在每个请求模型的线程中。当您有需要很长时间才能到达 exit/return 的阻塞呼叫时。
情况 1:如果您有固定的线程池,那么应用程序可能 运行 线程不足。
情况 2:如果您有动态增长的线程池,那么您的应用程序将遭受过多的上下文切换开销,并且还会 运行 由于内存中阻塞的线程过多而导致内存不足.
在所有情况下,除了等待某些 IO 或其他事件外,没有完成任何有用的工作。