From eb4e0a70ad4f4eec1b98e4263eac3b6e13176281 Mon Sep 17 00:00:00 2001 From: Oleg Kovalenko Date: Thu, 31 Dec 2020 12:14:33 +0100 Subject: [PATCH 1/2] Serial by chaining --- .../evolutiongaming/catshelper/Serial.scala | 47 +++++++------------ 1 file changed, 16 insertions(+), 31 deletions(-) diff --git a/core/src/main/scala/com/evolutiongaming/catshelper/Serial.scala b/core/src/main/scala/com/evolutiongaming/catshelper/Serial.scala index e53eb8bc..a135981d 100644 --- a/core/src/main/scala/com/evolutiongaming/catshelper/Serial.scala +++ b/core/src/main/scala/com/evolutiongaming/catshelper/Serial.scala @@ -19,44 +19,29 @@ object Serial { def of[F[_]: Concurrent]: F[Serial[F]] = { Ref[F] - .of(none[List[F[Unit]]]) + .of(().pure[F]) .map { ref => new Serial[F] { - def apply[A](fa: F[A]) = { - - def start(f: F[Unit]): F[Unit] = { - Nel - .of(f) - .tailRecM[F, Unit] { fs => - fs - .reverse - .foldMapM(identity) - .productR { - ref.modify { - case Some(f :: fs) => (List.empty[F[Unit]].some, Nel(f, fs).asLeft[Unit]) - case _ => (none[List[F[Unit]]], ().asRight[Nel[F[Unit]]]) - } - } - } - .start - .void - } + def apply[A](fa: F[A]): F[F[A]] = { Concurrent[F].uncancelable { for { - d <- Deferred.uncancelable[F, Either[Throwable, A]] - f = fa.attempt.flatMap { a => d.complete(a) } - r <- ref.modify { - case Some(fs) => ((f :: fs).some, ().pure[F]) - case None => (List.empty[F[Unit]].some, start(f)) - } - _ <- r - } yield for { - a <- d.get - a <- a.liftTo[F] - } yield a + deferred <- Deferred.uncancelable[F, Either[Throwable, A]] + gate <- Deferred.uncancelable[F, Unit] + next = gate.get + prev <- ref.modify { prev => (next, prev) } + task = for { + _ <- prev + a <- fa.attempt + _ <- gate.complete(()) + a <- deferred.complete(a) + } yield a + _ <- task.start + } yield { + deferred.get.rethrow + } } } } From de50b52e2a246cb3711b87da130806891dc0c25f Mon Sep 17 00:00:00 2001 From: Oleg Kovalenko Date: Thu, 31 Dec 2020 12:44:08 +0100 Subject: [PATCH 2/2] remove unused import --- core/src/main/scala/com/evolutiongaming/catshelper/Serial.scala | 1 - 1 file changed, 1 deletion(-) diff --git a/core/src/main/scala/com/evolutiongaming/catshelper/Serial.scala b/core/src/main/scala/com/evolutiongaming/catshelper/Serial.scala index a135981d..144a16c6 100644 --- a/core/src/main/scala/com/evolutiongaming/catshelper/Serial.scala +++ b/core/src/main/scala/com/evolutiongaming/catshelper/Serial.scala @@ -1,6 +1,5 @@ package com.evolutiongaming.catshelper -import cats.data.{NonEmptyList => Nel} import cats.effect.Concurrent import cats.effect.concurrent.{Deferred, Ref} import cats.effect.implicits._