Reputation: 5763
This is what I tried, but it is not cancelable after the first sleep finished.
import cats.syntax.all._
import cats.effect._
import scala.concurrent.duration._
import scala.language.higherKinds
object Foo {
def setInterval[F[_]](duration: FiniteDuration)(
fa: F[Unit]
)(implicit F: ConcurrentEffect[F], T: Timer[F]): F[IO[Unit]] = {
def run: F[Unit] = {
T.sleep(duration) *>
F.liftIO(F.runAsync(F.suspend(run))(_ => IO.unit)) *> fa
}
F.liftIO(F.runCancelable(run)(_ => IO.unit))
}
}
How could I implement a real cancelable setInterval
?
Upvotes: 1
Views: 519
Reputation: 5763
With the help of Fabio Labella , I recognized the
F.liftIO(F.runAsync(F.suspend(run))(_ => IO.unit)) *> fa
runAsync
just make the next recursive call run in background and be uncuncancelable, so I had to make fa
in the background instead, just like this
F.liftIO(F.runAsync(fa)(_ => IO.unit)) *> F.suspend(run)
Upvotes: 1