Because Task.parSequenceUnordered "is like parSequence, except that you don’t get ordering for results or effects.", I would expect the following to return List(2, 1):
import monix.eval.Task
import monix.execution.Scheduler.Implicits.global
object TaskSequence extends App {
val taskOne = Task {
Thread.sleep(3000)
println("First executed")
1
}
val taskTwo = Task {
Thread.sleep(2000)
println("Second executed")
2
}
val parallelUnordered = Task.parSequenceUnordered(List(taskOne, taskTwo)).runSyncUnsafe()
println(s"Return vals for Task.parSequenceUnordered( ) were $parallelUnordered")
}
However, I get List(1, 2) as a result. Using .runAsync( ) doesn't make a difference either:
Task.parSequenceUnordered(List(taskOne, taskTwo)).runAsync( result => result match {
case Right(value) => println(value)
case Left(value) => value
})
Thread.sleep(5000) // don't let program exit
The second Task finishes first, so I should get the 2 back first in the return List, right? Can any Monix experts weigh in? Thanks
It's because of the implementation of
parSequenceUnordered, which builds the result list by using O(1) prepend operations.There's a
to represent the internal state machine for the task, and a couple of the State subclasses look like
So because it uses
value :: listto accumulate the results, they are built in reverse in terms of which result comes in first.