Waitgroups in Scala

Our example demonstrates how to wait for multiple concurrent tasks to finish using Scala’s Future and Await. This is similar to the concept of wait groups in other languages.

import scala.concurrent.{Await, Future}
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration._

object WaitGroups {
  // This is the function we'll run in every Future
  def worker(id: Int): Unit = {
    println(s"Worker $id starting")
    // Sleep to simulate an expensive task
    Thread.sleep(1000)
    println(s"Worker $id done")
  }

  def main(args: Array[String]): Unit = {
    // Create a list of Futures
    val futures = (1 to 5).map { i =>
      Future {
        worker(i)
      }
    }

    // Wait for all Futures to complete
    Await.result(Future.sequence(futures), 5.seconds)

    // Note that this approach doesn't provide a straightforward way
    // to propagate errors from workers. For more advanced use cases,
    // consider using libraries like Cats Effect or ZIO.
  }
}

To run the program:

$ scala WaitGroups.scala
Worker 1 starting
Worker 5 starting
Worker 2 starting
Worker 4 starting
Worker 3 starting
Worker 1 done
Worker 5 done
Worker 2 done
Worker 4 done
Worker 3 done

The order of workers starting up and finishing is likely to be different for each invocation.

In this Scala version:

  1. We use Future to represent asynchronous computations, similar to goroutines.
  2. The worker function is defined similarly to the original example.
  3. In the main function, we create a list of Futures using map over a range of 1 to 5.
  4. We use Future.sequence to convert our list of Futures into a Future of a list of results.
  5. Await.result is used to block until all Futures complete, similar to WaitGroup.Wait().
  6. We use a timeout of 5 seconds in Await.result, but this can be adjusted as needed.

Note that Scala’s Futures and Await provide similar functionality to wait groups, but with a different API. Scala also offers more advanced concurrency libraries like Cats Effect or ZIO for more complex scenarios.