Search code examples
scalascala-catscats-effect

Launching 100 fibers, iterating in each fiber and incrementing a Ref


I want to do the following:

  1. Create 100 fibers

  2. In each fiber, loop 1000 times and increment my Ref

  3. After each fiber has completed 1000 iterations, shutdown the fiber

  4. Before exiting the program, output the current value of the Ref.

    object Fibers extends IOApp.Simple {
    
       val program =
         for {
           ref <- Ref.of[IO, Int](0)
           total <- ref.get
           _ <- IO(println(s"ref total is: ${total}"))
         } yield ()
    
       override def run: IO[Unit] = program
    
     }
    

I also want to time how long this takes to complete (in milliseconds)...


Solution

  • This is the code you want.

    object Fibers extends IOApp.Simple {
      private def logic(ref: Ref[IO, Int], nFibers: Int, nIterations: Int): IO[Unit] =
        List.range(start = 0, end = nFibers).parTraverse_ { _ =>
          List.range(start = 0, end = nIterations).traverse_ { _ =>
            ref.update(_ + 1)
          }
        }
    
      override final val run: IO[Unit] =
        IO.ref(0).flatTap { ref =>
          logic(ref, nFibers = 100, nIterations = 1000)
        } flatMap { ref =>
          ref.get.flatMap { total =>
            IO.println(s"Total is: ${total}")
          }
        }
    }
    

    Now, for benchmarking it please refer to a proper benchmarking tool.