Skip to content

Instantly share code, notes, and snippets.

@phongngtuan
Created March 12, 2019 04:19
Show Gist options
  • Select an option

  • Save phongngtuan/3e6e326e28a492866b9a2fad0a14099e to your computer and use it in GitHub Desktop.

Select an option

Save phongngtuan/3e6e326e28a492866b9a2fad0a14099e to your computer and use it in GitHub Desktop.
import cats._
import cats.implicits._
import cats.effect._
import scala.concurrent.duration._
object ProcessIO {
import scala.sys.process._
def exec[F[_]](commands: String)(implicit F: ConcurrentEffect[F], T: Timer[F]): F[Unit] = {
def acquire: F[Process] = F.delay(commands.run())
def release(process: Process): F[Unit] = F.delay(process.destroy()) *> F.delay(println("Process destroyed"))
def waitForExit(process: Process): F[Unit] = F.suspend(
if (process.isAlive)
F.delay(println("Waiting for process exit")) *> T.sleep(1.second) *> waitForExit(process)
else
F.delay(println("Process finished"))
)
F.bracket(acquire)(waitForExit)(release)
}
}
object Main extends IOApp {
import ProcessIO._
override def run( args: List[String] ): IO[ExitCode] = {
val command = "/usr/bin/sleep 10"
for {
cancel <- exec[IO](command).runCancelable(e => putStrLn(e.toString)).toIO
_ <- IO.sleep(5.seconds)
_ <- cancel.runAsync(_ => putStrLn("Cancelled")).toIO
} yield ExitCode.Success
}
def putStrLn(str: String) = IO.delay(println(str))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment