用开始时间和结束时间打包monix任务的最佳方法是什么?

N A*_*N A 5 scala monix

这就是我现在正在尝试但它只打印"嘿"而不是指标.我不想在main函数中添加与度量相关的东西.

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)
Run Code Online (Sandbox Code Playgroud)

Ale*_*lcu 9

你可以描述一个这样的函数:

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))
    )
  }
Run Code Online (Sandbox Code Playgroud)

一些建议:

  1. Task值应该是纯的,以及返回Tasks 的函数- 触发副作用的函数,并Task在结果被破坏时 返回
    • Task不是1:1的替代品Future; 在描述a时Task,应暂停(包裹)所有副作用Task
    • foreach触发了Task评估并且这不好,因为它会引发副作用; 我正在考虑弃用和删除它,因为它的存在很诱人
  2. 停止使用trait继承并只使用普通函数 - 除非你深刻理解OOP和子类型,否则最好尽可能避免使用它; 如果你进入蛋糕模式,停止这样做,也许加入支持小组
  3. 从来没有通过测量持续时间new Date(),你需要一个单调的时钟是和那就是JVM之上System.nanoTime,可以通过Monix的访问Scheduler通过clockMonotonic,如上述举例中,Scheduler经由给你deferAction
  4. 停止阻塞线程,因为这容易出错 - 而不是做Thread.sleep,做Task.sleep和所有Await.result调用都是有问题的,除非它们在main或不可能处理异步的其他地方

希望这可以帮助.

干杯,

  • 在最新版本的Task中,现在有一个Task.timed函数。 (3认同)