Skip to content

Instantly share code, notes, and snippets.

@pierangeloc
Last active June 12, 2019 21:32
Show Gist options
  • Save pierangeloc/286de276b5cdb35f3754b4d7e0510e3c to your computer and use it in GitHub Desktop.
Save pierangeloc/286de276b5cdb35f3754b4d7e0510e3c to your computer and use it in GitHub Desktop.
Don't use scala Future
trait TimedExecution {
implicit val materializer: Materializer
def delayed[A, B](f: A => B)(delay: FiniteDuration): A => Future[B] = a => Source.tick(delay, delay, a).take(1).map(f).runWith(Sink.head)
def delayedValue[A](a: => A)(delay: FiniteDuration): Future[A] = delayed[Unit, A](_ => a)(delay)(())
}
/**
* Utility functions to delay function executions or values. It needs a `Materializer` implicitly available
*
* Usage:
* ```
* val te = TimedExecution()
* import te._
*
* delayed[Int, Int](_ + 1)(5.seconds)
* ```
*/
object TimedExecution {
def apply()(implicit mat: Materializer): TimedExecution = new TimedExecution {
override implicit val materializer: Materializer = mat
}
}
object TestTraverse extends App {
import cats.implicits._
implicit val actorSystem = ActorSystem()
implicit val materializer = ActorMaterializer()
import actorSystem.dispatcher
val te = TimedExecution()
import te._
def attempt1: Unit = {
val start = System.nanoTime()
println(s"starting at $start")
val xs: Future[List[Int]] = List(1, 2, 3, 4).traverse(i => delayedValue(i)(i.seconds))
println("result: " + Await.result(xs, 30.seconds))
val end = System.nanoTime()
println(s"ended at $end")
println(s"it took ${(end - start) / 1000000} ms")
}
def attempt2: Unit = {
val start = System.nanoTime()
println(s"starting at $start")
val xs: Future[List[Int]] = List(1, 2, 3, 4).foldLeft(Future(List[Int]()))((f, i) => f.flatMap(xs => delayedValue(i)(i.seconds).map(_ :: xs)))
println("result: " + Await.result(xs, 30.seconds))
val end = System.nanoTime()
println(s"ended at $end")
println(s"it took ${(end - start) / 1000000} ms")
}
attempt1
println("### ATTEMPT WITH FOLDLEFT ###")
attempt2
}
object TestTraverseCatsEffect extends IOApp {
import cats.implicits._
def f(i: Int): IO[Int] = IO.sleep(i.seconds) *> IO.delay(i)
val prg: IO[Unit] = for {
start <- IO.delay(System.nanoTime())
_ <- IO.delay(println(s"starting at $start"))
res <- List(1, 2, 3, 4).traverse(f)
_ <- IO.delay(println(s"result: $res"))
end <- IO.delay(System.nanoTime())
_ <- IO.delay(println(s"it took ${(end - start) / 1000000} ms"))
} yield ()
override def run(args: List[String]): IO[ExitCode] = prg *> IO.delay(ExitCode.Success)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment