All Downloads are FREE. Search and download functionalities are using the official Maven repository.

cps.monads.catsEffect.CpsCERuntimeAwait.scala Maven / Gradle / Ivy

The newest version!
package cps.monads.catsEffect

import cps.*
import cats.effect.*
import cats.effect.std.Dispatcher

import scala.concurrent.{ExecutionException, blocking}
import java.util.concurrent.CompletableFuture
import scala.util.control.NonFatal

class CpsCERuntimeAwait[F[_]](dispatcher: Dispatcher[F], async: Async[F]) extends CpsRuntimeAwait[F] {

    override def await[A](fa: F[A])(ctx: CpsTryMonadContext[F]): A = {
         import scala.concurrent.ExecutionContext.Implicits.global
         val cf = CompletableFuture[A]()
         dispatcher.unsafeToFuture(fa).onComplete{
            case scala.util.Success(a) => cf.complete(a)
            case scala.util.Failure(ex) => cf.completeExceptionally(ex)
         }
         blocking {
           try {
             cf.get()
           } catch {
              case ex: ExecutionException =>
                throw ex.getCause()
           }
         }
    }

}

class CpsCERuntimeAwaitProvider[F[_]:Async] extends CpsRuntimeAwaitProvider[F] {

  def runInVirtualThread[A](op: =>A): F[A] =
    Async[F].async_{ cb =>
      Thread.ofVirtual().start(() => {
        try {
          val r = op
          cb(Right(r))
        }catch{
          case ec: ExecutionException =>
            cb(Left(ec.getCause()))
          case NonFatal(ex) =>
            cb(Left(ex))
        }
      })
    }

  override def withRuntimeAwait[A](op: CpsRuntimeAwait[F] => F[A])(using ctx:CpsTryMonadContext[F]): F[A] =
    Dispatcher.sequential[F].use{dispatcher =>
       val ra = CpsCERuntimeAwait(dispatcher, summon[Async[F]])
       ctx.monad.flatten(runInVirtualThread(op(ra)))
    }

}

given cpsCERuntimeAwaitProvider[F[_]](using Async[F]): CpsRuntimeAwaitProvider[F] =
         CpsCERuntimeAwaitProvider[F]




© 2015 - 2025 Weber Informatics LLC | Privacy Policy