Skip to content

Commit

Permalink
Fix resource leak in .toResourceZIO that could happen just after ZM…
Browse files Browse the repository at this point in the history
  • Loading branch information
neko-kai authored Oct 3, 2020
1 parent 1d9aae1 commit 5e320e3
Showing 1 changed file with 20 additions and 23 deletions.
43 changes: 20 additions & 23 deletions interop-cats/shared/src/main/scala/zio/interop/catszmanaged.scala
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,10 @@
package zio
package interop

import cats.~>
import cats.arrow.FunctionK
import cats.arrow.{ ArrowChoice, FunctionK }
import cats.effect.Resource.{ Allocate, Bind, Suspend }
import cats.effect.{ Async, Effect, ExitCase, LiftIO, Resource, Sync, IO => CIO }
import cats.{ Bifunctor, Monad, MonadError, Monoid, Semigroup, SemigroupK }
import cats.arrow.ArrowChoice
import cats.{ ~>, Bifunctor, Monad, MonadError, Monoid, Semigroup, SemigroupK }
import zio.ZManaged.ReleaseMap

trait CatsZManagedSyntax {
Expand Down Expand Up @@ -82,26 +80,25 @@ final class CatsIOResourceSyntax[F[_], A](private val resource: Resource[F, A])
final class ZManagedSyntax[R, E, A](private val managed: ZManaged[R, E, A]) extends AnyVal {

def toResourceZIO: Resource[ZIO[R, E, ?], A] =
Resource.suspend {
ZManaged.ReleaseMap.make.bracketExit(
release = (releaseMap: ReleaseMap, exit: Exit[E, _]) =>
exit match {
case Exit.Success(_) => UIO.unit
case Exit.Failure(_) => releaseMap.releaseAll(exit, ExecutionStrategy.Sequential)
},
use = releaseMap =>
managed.zio.provideSome[R]((_, releaseMap)).map {
case (_, a) =>
Resource.applyCase(ZIO.succeedNow {
(
a,
(exitCase: ExitCase[Throwable]) =>
releaseMap.releaseAll(exitCaseToExit(exitCase), ExecutionStrategy.Sequential).unit
)
})
}
Resource
.applyCase[ZIO[R, E, ?], ReleaseMap](
ZManaged.ReleaseMap.make.map(
releaseMap =>
(
releaseMap,
(exitCase: ExitCase[Throwable]) =>
releaseMap.releaseAll(exitCaseToExit(exitCase), ExecutionStrategy.Sequential).unit
)
)
)
.flatMap(
releaseMap =>
Resource.suspend(
managed.zio.provideSome[R]((_, releaseMap)).map { a =>
Resource.applyCase(ZIO.succeedNow((a._2, (_: ExitCase[Throwable]) => ZIO.unit)))
}
)
)
}

def toResource[F[_]](implicit F: Async[F], ev: Effect[ZIO[R, E, ?]]): Resource[F, A] =
toResourceZIO.mapK(Lambda[FunctionK[ZIO[R, E, ?], F]](F liftIO ev.toIO(_)))
Expand Down

0 comments on commit 5e320e3

Please sign in to comment.