Как измерить прошедшее время в эффекте ввода-вывода Cats? - PullRequest
0 голосов
/ 22 февраля 2019

Я бы хотел измерить прошедшее время внутри контейнера ввода-вывода.Это относительно просто сделать с простыми вызовами или фьючерсами (например, что-то вроде приведенного ниже кода)

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")
    }
  }

Спасибо!

1 Ответ

0 голосов
/ 22 февраля 2019

Cats-эффект имеет реализацию 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)
}
...