cats-effect
cats-effect copied to clipboard
Improve docs for using `IO` outside of `IOApp`
(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.
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
IOAppand what I'm losing by not using it. All of the advice is: UseIOApp.
https://discord.com/channels/632277896739946517/632278585700384799/959434688668262440
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.
@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))
}