Search code examples
scalascala-catscats-effect

Run a cats Resource in the infinite loop


I want to run a program: Resource in the infinite loop. I tried useForever. The application does not close but the program (for content) runs only once.

val program: Resource[IO, Unit] = 
  for {
    _ <- Resource.eval(engine.createSth)
    _ <- Resource.eval(IO.sleep(2 seconds)
  } yield ()

program.useForever.as(ExitCode.Success)

Solution

  • .useForever is used when you want to have a resource whose behavior is entirely in the acquire step. An example would be an http server. On resource acquire you bind to a port and start listening. Then it runs forever. All that .useForever does is prevent the resource from being closed. It's defined as = use(_ => IO.never)

    Instead you want the .foreverM combinator, which repeatedly flatMaps some monadic program with itself in an endless loop.

    program.foreverM
    

    However in this case there's no resource behavior at all - it's just two independent actions that are being wrapped in resources. You can skip that and instead have

    val run: IO[Nothing] = (engine.createSth >> IO.sleep(2.seconds)).foreverM