cats-effect icon indicating copy to clipboard operation
cats-effect copied to clipboard

Improve docs for using `IO` outside of `IOApp`

Open armanbilge opened this issue 3 years ago • 3 comments

(My summary/analysis of this Discord discussion.)

We push IOApp hard, with good reason.

However, if you want to use Cats Effect to build a library/module/component whatever that can be called from the outside world then IOApp is not an option. So perhaps we need a section describing good patterns for this.

armanbilge avatar Apr 01 '22 13:04 armanbilge

Relevant quote from @davesmith00000

I mean, the example is my use case. It was just unclear to me what the recommended approach was if you can't use an IOApp and what I'm losing by not using it. All of the advice is: Use IOApp.

https://discord.com/channels/632277896739946517/632278585700384799/959434688668262440

armanbilge avatar Apr 01 '22 14:04 armanbilge

While writing https://github.com/typelevel/cats-effect/issues/2928#issuecomment-1086044308 I was also reminded that feral is an example of this: you can't use IOApp inside of a serverless lambda.

armanbilge avatar Apr 01 '22 15:04 armanbilge

@Daenyth made a very nice example of how to do this Right:tm:. I think if we add it to our docs somewhere we can close this issue.

https://discord.com/channels/632277896739946517/839899003306901545/1111351658841133076

trait JavaLand {
  def doStuff: Unit
}

class IOLand {
  def doStuff: IO[Unit] = IO.println("yo")
}

class JavaLandIO(impl: IOLand, disp: Dispatcher[IO]) extends JavaLand {
  def doStuff = disp.unsafeRunSync(impl.doStuff)
}
object JavaLandIO {
  def createUnsafe(): (JavaLand, () => Unit) = {
    import cats.effect.unsafe.implicits.global
    val (impl, shutdown) = create.allocated.unsafeRunSync()
    (impl, () => shutdown.unsafeRunSync())
  }
  def create: Resource[IO, JavaLand] =
    Dispatcher[IO].map(disp => new JavaLandIO(new IOLand, disp))
}

armanbilge avatar May 25 '23 18:05 armanbilge