我想做这样的事情:
def warnEvery[A](duration: Duration)(block: => A): A = {
val start = DateTime.now
val f = Future(f)
while(!f.isComplete) {
Thread.sleep(duration)
if (!f.isComplete) {
// Trigger a stack trace warning message
Log.warn(s"Block is running for ${DateTime.now() - start}", new Throwable())
}
}
f.result
}
Run Code Online (Sandbox Code Playgroud)
目标是以这种方式使用上面的帮助器:
warnEvery(1 minute) {
// slow operation
}
Run Code Online (Sandbox Code Playgroud)
在我的日志中,我希望看到一个缓慢的代码块的堆栈跟踪.
在Scala中实现此目的的最佳方法是什么.指向现有库的指针也很好.
您可以使用Akka的调度程序来安排检查未来完成情况的任务.这样,就没有必要Thread.sleep在任务完成之前阻塞其线程.
def warnEvery[A](duration: FiniteDuration)(block: => A): Future[A] = {
val start = DateTime.now
val f = Future(f)
def warn {
if (!f.isCompleted) {
Log.warn(s"Block is running for ${DateTime.now() - start}")
Akka.system.scheduler.scheduleOnce(duration)(warn)
}
}
Akka.system.scheduler.scheduleOnce(duration)(warn)
f
}
Run Code Online (Sandbox Code Playgroud)
轻微的挑剔:从技术上讲,这个解决方案衡量的是创造未来与现在之间的时间.如果在创建未来时执行上下文中的所有线程都忙,则可能稍后开始执行该块.因此,更好的日志消息是"块已经排队等待执行......几秒钟之前尚未完成运行."