这是我现在正在尝试的方法,但它仅显示“嘿”,而不显示指标。 我不想在主要功能中添加与指标相关的内容。
import java.util.Date
import monix.eval.Task
import monix.execution.Scheduler.Implicits.global
import scala.concurrent.Await
import scala.concurrent.duration.Duration
class A {
def fellow(): Task[Unit] = {
val result = Task {
println("hey")
Thread.sleep(1000)
}
result
}
}
trait AA extends A {
override def fellow(): Task[Unit] = {
println("AA")
val result = super.fellow()
val start = new Date()
result.foreach(e => {
println("AA", new Date().getTime - start.getTime)
})
result
}
}
val a = new A with AA
val res: Task[Unit] = a.fellow()
Await.result(res.runAsync, Duration.Inf)
答案 0 :(得分:7)
您可以描述这样的功能:
def measure[A](task: Task[A], logMillis: Long => Task[Unit]): Task[A] =
Task.deferAction { sc =>
val start = sc.clockMonotonic(TimeUnit.MILLISECONDS)
val stopTimer = Task.suspend {
val end = sc.clockMonotonic(TimeUnit.MILLISECONDS)
logMillis(end - start)
}
task.redeemWith(
a => stopTimer.map(_ => a)
e => stopTimer.flatMap(_ => Task.raiseError(e))
)
}
一些建议:
Task
的值应该是纯净的,并且返回Task
的函数应该是纯函数,这些函数会触发副作用并在结果被破坏时返回Task
Task
不是Future
的1:1替代;描述Task
时,应将所有副作用都Task
中暂停(包装)foreach
触发Task
的评估,但效果不好,因为它会触发副作用;我一直在考虑弃用和删除它,因为它的存在很诱人new Date()
来测量持续时间,为此您需要一个单调时钟,并且在System.nanoTime
的JVM之上,{{1}可以通过Monix的Scheduler
访问它。 },如以上示例所示,clockMonotonic
是通过Scheduler
deferAction
,而是执行Thread.sleep
,否则所有Task.sleep
的调用都是有问题的,除非它们位于Await.result
或某些位置在不可能处理异步的其他地方希望这会有所帮助。
干杯
答案 1 :(得分:2)
就像@Pierre 提到的,最新版本的 Monix Task 有 Task.timed
,你可以做
timed <- task.timed
(duration, t) = timed