Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the best way to wrap a monix Task with a start time and end time print the difference?

Tags:

scala

monix

This is what I'm trying right now but it only prints "hey" and not metrics. I don't want to add metric related stuff in the main function.

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)
like image 905
N A Avatar asked Jun 22 '18 09:06

N A


People also ask

Do you need time or task management to get work done?

Even if we all have different tasks on our to-do list, we all have a similar purpose: to get as much done as possible. To this end, time and task management are two of the most popular strategies for getting organized and for getting work done. Still, with days limited to 24 hours, the big question is: which one is the best?

Is time management the best way to get things done?

In general, time management has long been considered one of the best strategies for getting things done. However… Time management works on the assumption that, if you learn to spend your time correctly, you will get more done. However, no matter how well you prioritize your time, you cannot work all day long.

What is the best way to wrap up a lesson?

Adult learners may write a business email with the new vocabulary they’ve learned. For very young ESL learners the best way to wrap up a lesson is with a goodbye song or saying goodbye to a puppet.


Video Answer


2 Answers

You can describe a function such as this:

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

Some piece of advice:

  1. Task values should be pure, along with the functions returning Tasks — functions that trigger side effects and return Task as results are broken
    • Task is not a 1:1 replacement for Future; when describing a Task, all side effects should be suspended (wrapped) in Task
    • foreach triggers the Task's evaluation and that's not good, because it triggers the side effects; I was thinking of deprecating and removing it, since its presence is tempting
  2. stop using trait inheritance and just use plain functions — unless you deeply understand OOP and subtyping, it's best to avoid it if possible; and if you're into the Cake pattern, stop doing it and maybe join a support group 🙂
  3. never measure time duration via new Date(), you need a monotonic clock for that and on top of the JVM that's System.nanoTime, which can be accessed via Monix's Scheduler by clockMonotonic, as exemplified above, the Scheduler being given to you via deferAction
  4. stop blocking threads, because that's error prone — instead of doing Thread.sleep, do Task.sleep and all Await.result calls are problematic, unless they are in main or in some other place where dealing with asynchrony is not possible

Hope this helps.

Cheers,

like image 78
Alexandru Nedelcu Avatar answered Nov 15 '22 06:11

Alexandru Nedelcu


Like @Pierre mentioned, latest version of Monix Task has Task.timed, you can do

timed <- task.timed
(duration, t) = timed
like image 23
Arun Gopalpuri Avatar answered Nov 15 '22 08:11

Arun Gopalpuri