jilen
jilen

Reputation: 5763

Implement cancelable setInterval using cats-effect's Timer

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

Answers (1)

jilen
jilen

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

Related Questions