Search code examples
scalanon-deterministicscalaz-streamfs2

Execute two fs2 tasks concurrently (non-determenistically)


With Scalaz Task I make this with scalaz.Nondeterminism.both:

Nondeterminism[Task]
 .both(
   Task.now("Hello"),
   Task.now("world")
 )

or with Nondeterminism[Task].gatherUnordered().

How can I do the same thing with fs2 0.9.x version tasks?


Solution

  • I'm assuming you're on fs2 version 0.9.x. To execute several Tasks in parallel, you can simply call Task.start. Here's an example from the docs:

    for {
       f <- Task.start { expensiveTask1 }
       // at this point, `expensive1` is evaluating in background
    
       g <- Task.start { expensiveTask2 }
       // now both `expensiveTask2` and `expensiveTask1` are running
    
       result1 <- f
       // we have forced `f`, so now only `expensiveTask2` may be running
    
       result2 <- g
       // we have forced `g`, so now nothing is running and we have both results
    
     } yield (result1 + result2)
    

    So in your case it would look like this:

    for {
      ta <- Task.start(Task.now("Hello"))
      tb <- Task.start(Task.now("World"))
      a <- ta
      b <- tb
    } yield (a, b)
    

    Note that in the future it might be possible to do something like this with much less boilerplate. There's a PR in the works to add a Parallel type class, which would allow us to write something like this:

    (taskA, taskB).parMapN((a, b) => ...)