【问题标题】:How do I measure elapsed time inside Cats IO effect?如何在 Cats IO 效果中测量经过的时间?
【发布时间】:2019-02-22 15:27:11
【问题描述】:

我想测量 IO 容器内经过的时间。使用普通调用或期货相对容易(例如下面的代码)

class MonitoringComponentSpec extends FunSuite with Matchers with ScalaFutures {

  import scala.concurrent.ExecutionContext.Implicits.global

  def meter[T](future: Future[T]): Future[T] = {
    val start = System.currentTimeMillis()
    future.onComplete(_ => println(s"Elapsed ${System.currentTimeMillis() - start}ms"))
    future
  }

  def call(): Future[String] = Future {
    Thread.sleep(500)
    "hello"
  }

  test("metered call") {
    whenReady(meter(call()), timeout(Span(550, Milliseconds))) { s =>
      s should be("hello")
    }
  }
}

但不确定如何包装 IO 调用

  def io_meter[T](effect: IO[T]): IO[T] = {
    val start = System.currentTimeMillis()
    ???
  }

  def io_call(): IO[String] = IO.pure {
    Thread.sleep(500)
    "hello"
  }

  test("metered io call") {
    whenReady(meter(call()), timeout(Span(550, Milliseconds))) { s =>
      s should be("hello")
    }
  }

谢谢!

【问题讨论】:

    标签: scala functional-programming scala-cats cats-effect


    【解决方案1】:

    Cats-effect 有一个 Clock 实现,它允许纯粹的时间测量以及注入您自己的实现以在您只想模拟时间流逝时进行测试。他们文档中的示例是:

    def measure[F[_], A](fa: F[A])
      (implicit F: Sync[F], clock: Clock[F]): F[(A, Long)] = {
    
      for {
        start  <- clock.monotonic(MILLISECONDS)
        result <- fa
        finish <- clock.monotonic(MILLISECONDS)
      } yield (result, finish - start)
    }
    

    【讨论】:

    • 这并不完全等同于 OP 的 Future 实现,尽管 Future.onComplete 会计时失败情况
    猜你喜欢
    • 1970-01-01
    • 2019-12-30
    • 2019-02-25
    • 1970-01-01
    • 2014-09-05
    • 2011-11-17
    相关资源
    最近更新 更多