While updating some examples that demonstrate what not to do, I bumped into this issue. Here's my example.
import scala.concurrent.duration._
import cats.effect._
import cats.effect.std.{ Semaphore, Supervisor }
import cats.effect.unsafe.implicits.global
object LeakyState extends IOApp.Simple {
// global access
val sem: Semaphore[IO] =
Semaphore[IO](1).unsafeRunSync()
def launchMissiles: IO[Unit] =
sem.permit
.use { _ =>
IO.println("Launching missiles") >>
IO.sleep(3.seconds) >>
IO.println("Missiles launched, releasing lock")
}
def randomSleep: IO[Unit] =
IO(scala.util.Random.nextInt(100)).flatMap { ms =>
IO.sleep((ms + 700).millis)
}.void
def p1: IO[Unit] =
sem.permit.use(_ => IO.println("Running P1")) >> randomSleep
def p2: IO[Unit] =
sem.permit.use(_ => IO.println("Running P2")) >> randomSleep
def run: IO[Unit] =
Supervisor[IO].use { s =>
s.supervise(launchMissiles) *>
s.supervise(p1.foreverM).void *>
s.supervise(p2.foreverM).void *>
IO.sleep(5.seconds).void
}
}
Initializing (unsafely) the Semaphore fails with this error.
[info] running (fork) examples.state.LeakyState
[error] Exception in thread "main" java.lang.IllegalArgumentException: requirement failed
[error] at scala.Predef$.require(Predef.scala:325)
[error] at cats.effect.unsafe.IORuntimeCompanionPlatform.installGlobal(IORuntimeCompanionPlatform.scala:67)
[error] at cats.effect.IOApp.main(IOApp.scala:58)
[error] at cats.effect.IOApp.main$(IOApp.scala:35)
[error] at examples.state.LeakyState$.main(LeakyState.scala:9)
[error] at examples.state.LeakyState.main(LeakyState.scala)
Even when setting Compile / run / fork := true in build.sbt.
The workaround is to make it a lazy val together with forking enabled in sbt. So this does not work in Scastie: https://scastie.scala-lang.org/v7S7tnCsQ9yAL9gMSnxyhw
Since this example showcases exactly what users should not do, I don't expect a fix but raising the issue in case this could be a legit bug when interoping with side-effectful frameworks, e.g. initializing an ActorSystem within IOApp.
While updating some examples that demonstrate what not to do, I bumped into this issue. Here's my example.
Initializing (unsafely) the
Semaphorefails with this error.Even when setting
Compile / run / fork := trueinbuild.sbt.The workaround is to make it a
lazy valtogether with forking enabled insbt. So this does not work in Scastie: https://scastie.scala-lang.org/v7S7tnCsQ9yAL9gMSnxyhwSince this example showcases exactly what users should not do, I don't expect a fix but raising the issue in case this could be a legit bug when interoping with side-effectful frameworks, e.g. initializing an
ActorSystemwithinIOApp.