New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proposal: make mapBoth always execute tasks in parallel #661

Merged
merged 1 commit into from Apr 29, 2018

Conversation

Projects
None yet
2 participants
@oleg-py
Collaborator

oleg-py commented Apr 22, 2018

Got caught up by surprise by the following behavior:

import cats._, implicits._, effect._, monix.eval._
import java.util.concurrent.TimeUnit
import monix.execution.Scheduler.Implicits.global
import scala.concurrent.duration._

// Imagine this is some blocking operation
val blockingOp = Task.eval { Thread.sleep(1000) }

val nowL = Timer[Task].clockMonotonic(TimeUnit.SECONDS)

val task = for {
  start <- nowL
  _ <- Task.zip4(blockingOp, blockingOp, blockingOp, blockingOp)
  end <- nowL
  _ <- Task.eval(println(s"${end - start}s passed")) // 4s passed, expected: 1s
} yield ()

task.runSyncUnsafe(Duration.Inf)

This happens if Task is constructed by .eval as opposed to .apply (which I do all the time since this way I can control behavior later). In real example I have a flatMap-chain of Tasks built on Task.eval.

This affects Task.zipX, Task.parMapX and also Parallel instance. I think it makes sense to always fork inside mapBoth because it's more likely to be what user expects.

@alexandru alexandru merged commit 4b99f39 into monix:master Apr 29, 2018

@alexandru

This comment has been minimized.

Member

alexandru commented Apr 29, 2018

I agree with this change.

Had to force merge it because Travis is malfunctioning.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment