Это то, что я пробую прямо сейчас, но он выводит только "привет", а не показатели. Я не хочу добавлять вещи, связанные с метрикой, в основную функцию.

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)
6
N A 22 Июн 2018 в 12:20

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

Какой-то совет:

  1. Значения Task должны быть чистыми, вместе с функциями, возвращающими Task s - функции, которые вызывают побочные эффекты и возвращают Task, если результаты не работают.
    • Task не является заменой 1: 1 для Future; при описании Task все побочные эффекты должны быть приостановлены (заключены) в Task
    • foreach запускает оценку Task, и это нехорошо, поскольку вызывает побочные эффекты; Я подумывал отказаться от него и удалить его, так как его присутствие заманчиво.
  2. прекратите использовать наследование признаков и просто используйте простые функции - если вы глубоко не разбираетесь в ООП и подтипах, лучше по возможности избегать этого; и если вам нравится паттерн торт, перестаньте его делать и, возможно, присоединитесь к группе поддержки 🙂
  3. никогда не измеряйте продолжительность времени через new Date(), для этого вам нужны монотонные часы, а также поверх JVM, которая System.nanoTime, к которой можно получить доступ через Scheduler Monix через clockMonotonic, так как как указано выше, Scheduler передается вам через deferAction
  4. прекратите блокировать потоки, потому что это подвержено ошибкам - вместо выполнения Thread.sleep выполните Task.sleep, и все вызовы Await.result будут проблематичными, если только они не находятся в main или в другом месте, где работа с асинхронностью невозможна

Надеюсь это поможет.

Ура ,

11
Alexandru Nedelcu 22 Июн 2018 в 09:58

Как упоминал @Pierre, в последней версии Monix Task есть Task.timed, вы можете

timed <- task.timed
(duration, t) = timed
2
Arun Gopalpuri 21 Дек 2020 в 22:20