diff --git a/lab10/build.sbt b/lab10/build.sbt new file mode 100644 index 0000000..426c33d --- /dev/null +++ b/lab10/build.sbt @@ -0,0 +1,18 @@ +name := "lab10" + +version := "0.1" + +scalaVersion := "2.12.11" + +libraryDependencies += "org.typelevel" %% "cats-core" % "2.0.0" +libraryDependencies += "org.scalatest" %% "scalatest" % "3.1.1" % "test" + +libraryDependencies += "org.typelevel" %% "cats-effect" % "1.3.0" withSources() withJavadoc() + +scalacOptions ++= Seq( + "-feature", + "-deprecation", + "-unchecked", + "-language:postfixOps", + "-language:higherKinds", + "-Ypartial-unification") \ No newline at end of file diff --git a/lab10/project/build.properties b/lab10/project/build.properties new file mode 100644 index 0000000..f37b0aa --- /dev/null +++ b/lab10/project/build.properties @@ -0,0 +1 @@ +sbt.version = 1.3.10 \ No newline at end of file diff --git a/lab10/src/main/scala/Main.scala b/lab10/src/main/scala/Main.scala new file mode 100644 index 0000000..059341d --- /dev/null +++ b/lab10/src/main/scala/Main.scala @@ -0,0 +1,36 @@ +import cats.effect.{ExitCode, IO, IOApp, Resource} +import cats.effect.concurrent.MVar +import cats.syntax.all._ + +import scala.concurrent.duration._ + +object Main extends IOApp { + def runPrinter(mvar: MVar[IO, String]): Resource[IO, Unit] = { + def rec: IO[Unit] = for { + value <- mvar.take + _ <- IO(println(value)) + _ <- rec + } yield () + + Resource.make(rec.start)(_.cancel.flatMap(_ => IO(println("printer is closed")))).void + } + + def runCounter(mvar: MVar[IO, String]): Resource[IO, Unit] = { + def rec(counter: Long): IO[Unit] = for { + _ <- IO.sleep(1.seconds) + _ <- mvar.put(counter.toString) + _ <- rec(counter + 1) + } yield () + + Resource.make(rec(0).start)(_.cancel.flatMap(_ => IO(println("counter is closed")))).void + } + + val gracefulShutdownProgram: Resource[IO, Unit] = for { + mvar <- Resource.make(MVar.empty[IO, String])(_ => IO(print("release"))) + _ <- runCounter(mvar) + _ <- runPrinter(mvar) + } yield () + + override def run(args: List[String]): IO[ExitCode] = + gracefulShutdownProgram.use(_ => IO.never) +} \ No newline at end of file