evolution-gaming / cats-helper

Helpers for cats & cats-effect
MIT License
49 stars 17 forks source link

Accumulative timeout in ToTry #198

Closed dfakhritdinov closed 1 year ago

dfakhritdinov commented 1 year ago

Some cases like skafka #125 required applying ToTry multiple times while accumulating total execution time and firing IO.timeout on its exhaustion.

That can be achieved by implementing factory ToTryOf with API like:

import cats.effect.IO
import cats.effect.unsafe.IORuntime

sealed trait ToTryOf[F[_]] {
  def disposable(timeout: FiniteDuration): F[ToTry[F]]
}

object ToTryOf {
  def ioToTryOf(implicit runtime: IORuntime): ToTryOf[IO] = ???
}
t3hnar commented 1 year ago

that's definitely not a generic thing, we might have something like that in skafka directly

However I still do not understand how you can use that?

For instance in skafka we combine all things smart enough so we do block as rare as possible.

dfakhritdinov commented 1 year ago

The idea behind my proposal is in creating ToTry that will accumulate time taken to execute all effects and raise error if their total execution time exceeds timeout, example:

val toTryOf: ToTryOf[IO] = ???

val foo: Try[Unit] = for {
  implicit0(toTry: ToTry[IO]) <- toTryOf. disposable(10.seconds)
  _ <- IO.sleep(4.seconds).toTry // success
  _ <- IO.sleep(4.seconds).toTry // success
  _ <- IO.sleep(4.seconds).toTry // timeout exception as total execution time is ~12 seconds
  // all further usages of the `toTry` will raise timeout exception immediately 
} yield {}

Now, after taking more detailed look at skafka' RebalanceListener1 I got doubts that the proposal makes sense -- Kafka consumer, available as part of rebalance listener provides access to lots of blocking operations that includes I/O. Time taken by the consumer operations must also be considered in calculation of timeout, that's out of ToTry scope.