Каков наилучший способ обернуть задачу моникса временем начала и окончания печати?
Это то, что я пытаюсь сейчас, но он печатает только "эй", а не метрики. Я не хочу добавлять метрическую информацию в основную функцию.
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)
2 ответа
Решение
Вы можете описать такую функцию:
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
s - функции, которые запускают побочные эффекты и возвращаютTask
как результаты сломаныTask
не является заменой 1:1 дляFuture
; при описанииTask
, все побочные эффекты должны быть приостановленыTask
foreach
вызываетTask
оценка и это не хорошо, потому что это вызывает побочные эффекты; Я думал об устаревании и удалении его, так как его присутствие заманчиво
- прекратите использовать наследование признаков и просто используйте простые функции - если вы не глубоко понимаете ООП и подтипы, лучше по возможности избегать их; и если вы в шаблоне Cake, прекратите это делать и, возможно, присоединитесь к группе поддержки
- никогда не измеряйте продолжительность времени с помощью
new Date()
вам нужны монотонные часы для этого и на вершине JVM этоSystem.nanoTime
, который может быть доступен через Monix'sScheduler
отclockMonotonic
как показано выше,Scheduler
дается вам черезdeferAction
- прекратить блокировать потоки, потому что это подвержено ошибкам - вместо того, чтобы делать
Thread.sleep
, делатьTask.sleep
и всеAwait.result
вызовы проблематичны, если они не находятся вmain
или в каком-то другом месте, где невозможно работать с асинхронностью
Надеюсь это поможет.
Ура,
Как упоминалось @Pierre, последняя версия Monix Task имеет
Task.timed
, ты можешь сделать
timed <- task.timed
(duration, t) = timed