Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove unsafeRun in .toResource, preserve interruptibility of Reservation in Resource. add .toResourceZIO #10

Merged
merged 2 commits into from
Jun 29, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .jvmopts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
-Xss2M
2 changes: 2 additions & 0 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import sbtcrossproject.CrossPlugin.autoImport.crossProject
import explicitdeps.ExplicitDepsPlugin.autoImport.moduleFilterRemoveValue
import ScalazBuild._

name := "interop-cats"

inThisBuild(
List(
organization := "dev.zio",
Expand Down
22 changes: 11 additions & 11 deletions interop-cats/jvm/src/main/scala/zio/interop/catszmanagedjvm.scala
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ package interop

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

trait CatsZManagedSyntax {
import scala.language.implicitConversions
Expand All @@ -39,7 +39,7 @@ final class CatsIOResourceSyntax[F[_], A](private val resource: Resource[F, A])
* Convert a cats Resource into a ZManaged.
* Beware that unhandled error during release of the resource will result in the fiber dying.
*/
def toManaged[R](implicit l: LiftIO[ZIO[R, Throwable, ?]], ev: ConcurrentEffect[F]): ZManaged[R, Throwable, A] = {
def toManaged[R](implicit l: LiftIO[ZIO[R, Throwable, ?]], ev: Effect[F]): ZManaged[R, Throwable, A] = {
def convert[A1](resource: Resource[CIO, A1]): ZManaged[R, Throwable, A1] =
resource match {
case Allocate(res) =>
Expand Down Expand Up @@ -69,13 +69,13 @@ 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 toResource[F[_]](implicit r: Runtime[R], S: Sync[F]): Resource[F, A] =
Resource.suspend(S.delay {
r.unsafeRun(managed.reserve) match {
case Reservation(acquire, release) =>
Resource.make(S.delay(r.unsafeRun(acquire)))(_ => S.delay(r.unsafeRun(release.unit)))
}
})
def toResourceZIO(implicit ev: Applicative[ZIO[R, E, ?]]): Resource[ZIO[R, E, ?], A] =
Resource
.make(managed.reserve)(_.release.unit)
.evalMap(_.acquire)

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 All @@ -95,7 +95,7 @@ trait CatsZManagedInstances extends CatsZManagedInstances1 {
implicit ev: LiftIO[ZIO[R, Throwable, ?]]
): LiftIO[ZManaged[R, Throwable, ?]] =
new LiftIO[ZManaged[R, Throwable, ?]] {
override def liftIO[A](ioa: effect.IO[A]): ZManaged[R, Throwable, A] =
override def liftIO[A](ioa: CIO[A]): ZManaged[R, Throwable, A] =
ZManaged.fromEffect(ev.liftIO(ioa))
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
package zio.interop

import cats.effect.Resource
import java.util.concurrent.TimeUnit

import cats.effect.{ Concurrent, ContextShift, Resource, Timer, IO => CIO }
import cats.syntax.apply._
import cats.syntax.functor._
import org.specs2.Specification
import org.specs2.specification.AroundTimeout
import zio.{ DefaultRuntime, Task, ZIO, ZManaged }
import zio.{ DefaultRuntime, IO, Promise, Reservation, UIO, ZIO, ZManaged }
import zio.interop.catz._

import scala.collection.mutable
import scala.concurrent.ExecutionContext.global
import scala.concurrent.duration.FiniteDuration

class CatsZManagedSyntaxSpec extends Specification with AroundTimeout with DefaultRuntime {

Expand All @@ -24,12 +30,13 @@ class CatsZManagedSyntaxSpec extends Specification with AroundTimeout with Defau
calls finalizers when using resource $toResourceFinalizers
calls finalizers when using resource fails $toResourceFinalizersWhenFailed
calls finalizers when using resource is canceled $toResourceFinalizersWhenCanceled
acquisition of Reservation preserves cancellability in new F $toResourceCancelableReservationAcquisition
"""

def toManagedFinalizersWhenInterrupted = {
val effects = new mutable.ListBuffer[Int]
def res(x: Int): Resource[Task, Unit] =
Resource.make(ZIO.effect { effects += x; () })(_ => ZIO.effect { effects += x; () })
def res(x: Int): Resource[CIO, Unit] =
Resource.make(CIO.delay { effects += x; () })(_ => CIO.delay { effects += x; () })

val testCase = ZIO.runtime[Any].flatMap { implicit r =>
val managed: ZManaged[Any, Throwable, Unit] = res(1).toManaged
Expand All @@ -42,8 +49,8 @@ class CatsZManagedSyntaxSpec extends Specification with AroundTimeout with Defau

def toManagedFinalizersWhenFailed = {
val effects = new mutable.ListBuffer[Int]
def res(x: Int): Resource[Task, Unit] =
Resource.make(ZIO.effect { effects += x; () })(_ => ZIO.effect { effects += x; () })
def res(x: Int): Resource[CIO, Unit] =
Resource.make(CIO.delay { effects += x; () })(_ => CIO.delay { effects += x; () })

val testCase = ZIO.runtime[Any].flatMap { implicit r =>
val managed: ZManaged[Any, Throwable, Unit] = res(1).toManaged
Expand All @@ -56,8 +63,8 @@ class CatsZManagedSyntaxSpec extends Specification with AroundTimeout with Defau

def toManagedFinalizersWhenDied = {
val effects = new mutable.ListBuffer[Int]
def res(x: Int): Resource[Task, Unit] =
Resource.make(ZIO.effect { effects += x; () })(_ => ZIO.effect { effects += x; () })
def res(x: Int): Resource[CIO, Unit] =
Resource.make(CIO.delay { effects += x; () })(_ => CIO.delay { effects += x; () })

val testCase = ZIO.runtime[Any].flatMap { implicit r =>
val managed: ZManaged[Any, Throwable, Unit] = res(1).toManaged
Expand All @@ -70,9 +77,9 @@ class CatsZManagedSyntaxSpec extends Specification with AroundTimeout with Defau

def toManagedFinalizersExceptionAcquisition = {
val effects = new mutable.ListBuffer[Int]
def res(x: Int): Resource[Task, Unit] =
Resource.make(ZIO.effect(effects += x) *> ZIO.effect(throw new RuntimeException()).unit)(
_ => ZIO.effect { effects += x; () }
def res(x: Int): Resource[CIO, Unit] =
Resource.make(CIO.delay(effects += x) *> CIO.delay(throw new RuntimeException()).void)(
_ => CIO.delay { effects += x; () }
)

val testCase = ZIO.runtime[Any].flatMap { implicit r =>
Expand All @@ -86,8 +93,8 @@ class CatsZManagedSyntaxSpec extends Specification with AroundTimeout with Defau

def toManagedFinalizers = {
val effects = new mutable.ListBuffer[Int]
def res(x: Int): Resource[Task, Unit] =
Resource.make(ZIO.effect { effects += x; () })(_ => ZIO.effect { effects += x; () })
def res(x: Int): Resource[CIO, Unit] =
Resource.make(CIO.delay { effects += x; () })(_ => CIO.delay { effects += x; () })

val testCase = ZIO.runtime[Any].flatMap { implicit r =>
val managed: ZManaged[Any, Throwable, Unit] = res(1).toManaged
Expand All @@ -101,8 +108,8 @@ class CatsZManagedSyntaxSpec extends Specification with AroundTimeout with Defau
def toManagedComposition = {

val effects = new mutable.ListBuffer[Int]
def res(x: Int): Resource[Task, Unit] =
Resource.make(ZIO.effect { effects += x; () })(_ => ZIO.effect { effects += x; () })
def res(x: Int): Resource[CIO, Unit] =
Resource.make(CIO.delay { effects += x; () })(_ => CIO.delay { effects += x; () })

def man(x: Int): ZManaged[Any, Throwable, Unit] =
ZManaged.make(ZIO.effectTotal(effects += x).unit)(_ => ZIO.effectTotal(effects += x))
Expand Down Expand Up @@ -157,4 +164,24 @@ class CatsZManagedSyntaxSpec extends Specification with AroundTimeout with Defau
effects must be_===(List(1, 1))
}

def toResourceCancelableReservationAcquisition =
unsafeRun {
ZIO.runtime[Any] >>= { implicit runtime =>
implicit val ctx: ContextShift[CIO] = CIO.contextShift(global)
implicit val timer: Timer[CIO] = CIO.timer(global)

for {
latch <- Promise.make[Nothing, Unit]
managed = ZManaged.reserve(Reservation(latch.await, ZIO.unit))
resource = managed.toResource[CIO]
res <- IO {
Concurrent
.timeout(resource.use(_ => CIO.unit), FiniteDuration(0, TimeUnit.SECONDS))
.unsafeRunSync()
}.const(false) orElse UIO(true)
_ <- latch.succeed(())
} yield res must_=== true
}
}

}