Last active
June 12, 2019 21:32
-
-
Save pierangeloc/286de276b5cdb35f3754b4d7e0510e3c to your computer and use it in GitHub Desktop.
Don't use scala Future
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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