Skip to content

Commit

Permalink
Upgrade to ZIO 2.0.0-RC3 (#515)
Browse files Browse the repository at this point in the history
* upgrade to rc3

* fix tests

* format

* add type annotation
  • Loading branch information
adamgfraser authored Mar 23, 2022
1 parent 5a813cf commit 5e028e9
Show file tree
Hide file tree
Showing 13 changed files with 112 additions and 66 deletions.
6 changes: 5 additions & 1 deletion build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ lazy val root = project
unusedCompileDependenciesFilter -= moduleFilter("org.scala-js", "scalajs-library")
)

val zioVersion = "2.0.0-RC2"
val zioVersion = "2.0.0-RC3"
val catsVersion = "2.6.1"
val catsEffectVersion = "3.2.9"
val catsMtlVersion = "1.2.1"
Expand All @@ -63,6 +63,7 @@ lazy val zioInteropCats = crossProject(JSPlatform, JVMPlatform)
.settings(
libraryDependencies ++= {
val optLibraries0 = List(
"dev.zio" %%% "zio-managed" % zioVersion,
"dev.zio" %%% "zio-streams" % zioVersion,
"dev.zio" %%% "zio-stacktracer" % zioVersion,
"org.typelevel" %%% "cats-effect-std" % catsEffectVersion,
Expand All @@ -88,6 +89,7 @@ lazy val zioInteropCatsTests = crossProject(JSPlatform, JVMPlatform)
.settings(
libraryDependencies ++= {
val optLibraries0 = List(
"dev.zio" %%% "zio-managed" % zioVersion,
"dev.zio" %%% "zio-streams" % zioVersion,
"org.typelevel" %%% "cats-effect-std" % catsEffectVersion,
"org.typelevel" %%% "cats-mtl" % catsMtlVersion,
Expand Down Expand Up @@ -122,6 +124,7 @@ lazy val zioTestInteropCats = crossProject(JSPlatform, JVMPlatform)
.settings(
libraryDependencies ++= {
val optLibraries0 = List(
"dev.zio" %%% "zio-managed" % zioVersion,
"dev.zio" %%% "zio-streams" % zioVersion,
"dev.zio" %%% "zio-test" % zioVersion,
"org.typelevel" %%% "cats-effect-std" % catsEffectVersion,
Expand Down Expand Up @@ -155,6 +158,7 @@ lazy val coreOnlyTest = crossProject(JSPlatform, JVMPlatform)
.settings(
libraryDependencies ++= Seq(
"org.typelevel" %%% "cats-core" % catsVersion,
"dev.zio" %%% "zio-managed" % zioVersion,
"dev.zio" %%% "zio-test-sbt" % zioVersion
).map(_ % Test)
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import cats.data.NonEmptyList
import cats.{ Bifunctor, Monad, MonadError, SemigroupK }
import zio.*
import zio.interop.catz.core.*
import zio.managed.*
import zio.stream.interop.catz.core.*
import zio.stream.{ Stream, ZStream }
import zio.test.*
Expand Down
3 changes: 1 addition & 2 deletions project/BuildHelper.scala
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ object BuildHelper {
"-Yrangepos",
"-Xsource:3",
"-P:kind-projector:underscore-placeholders",
"-Xlint:_,-type-parameter-shadow",
"-Xlint:_,-type-parameter-shadow,-infer-any",
"-Ywarn-numeric-widen",
"-Ywarn-value-discard"
)
Expand Down Expand Up @@ -71,7 +71,6 @@ object BuildHelper {
"-Ypartial-unification",
"-Yno-adapted-args",
"-Ywarn-inaccessible",
"-Ywarn-infer-any",
"-Ywarn-nullary-override",
"-Ywarn-nullary-unit"
) ++ std2xOptions ++ optimizerOptions
Expand Down
2 changes: 1 addition & 1 deletion project/plugins.sbt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.7.0")
addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.8.0")
addSbtPlugin("org.portable-scala" % "sbt-scalajs-crossproject" % "1.1.0")
addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.4.3")
addSbtPlugin("com.eed3si9n" % "sbt-buildinfo" % "0.10.0")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import cats.effect.kernel.Resource
import cats.effect.IO as CIO
import zio.*
import zio.interop.catz.*
import zio.managed.*
import zio.test.Assertion.*
import zio.test.*

Expand Down Expand Up @@ -130,9 +131,9 @@ object CatsZManagedSyntaxSpec extends CatsRunnableSpec {
test("calls finalizers correctly when use is interrupted") {
val effects = new mutable.ListBuffer[Int]
def res(x: Int): Resource[Task, Unit] =
Resource.makeCase(Task(effects += x).unit) {
Resource.makeCase(Task.attempt(effects += x).unit) {
case (_, Resource.ExitCase.Canceled) =>
Task(effects += x + 1).unit
Task.attempt(effects += x + 1).unit
case _ => Task.unit
}

Expand All @@ -149,9 +150,9 @@ object CatsZManagedSyntaxSpec extends CatsRunnableSpec {
test("calls finalizers correctly when use has failed") {
val effects = new mutable.ListBuffer[Int]
def res(x: Int): Resource[Task, Unit] =
Resource.makeCase(Task(effects += x).unit) {
Resource.makeCase(Task.attempt(effects += x).unit) {
case (_, Resource.ExitCase.Errored(_)) =>
Task(effects += x + 1).unit
Task.attempt(effects += x + 1).unit
case _ =>
Task.unit
}
Expand All @@ -169,9 +170,9 @@ object CatsZManagedSyntaxSpec extends CatsRunnableSpec {
test("calls finalizers correctly when use has died") {
val effects = new mutable.ListBuffer[Int]
def res(x: Int): Resource[Task, Unit] =
Resource.makeCase(Task(effects += x).unit) {
Resource.makeCase(Task.attempt(effects += x).unit) {
case (_, Resource.ExitCase.Errored(_)) =>
Task(effects += x + 1).unit
Task.attempt(effects += x + 1).unit
case _ =>
Task.unit
}
Expand All @@ -189,8 +190,8 @@ object CatsZManagedSyntaxSpec extends CatsRunnableSpec {
test("calls finalizers should not run if exception is thrown in acquisition") {
val effects = new mutable.ListBuffer[Int]
def res(x: Int): Resource[Task, Unit] =
Resource.make(Task(effects += x) *> Task(throw new RuntimeException()).unit)(_ =>
Task(effects += x + 1).unit
Resource.make(Task.attempt(effects += x) *> Task.attempt(throw new RuntimeException()).unit)(_ =>
Task.attempt(effects += x + 1).unit
)

val testCase = {
Expand All @@ -206,7 +207,7 @@ object CatsZManagedSyntaxSpec extends CatsRunnableSpec {
test("calls finalizers correctly when using the resource") {
val effects = new mutable.ListBuffer[Int]
def res(x: Int): Resource[Task, Unit] =
Resource.make(Task(effects += x).unit)(_ => Task(effects += x).unit)
Resource.make(Task.attempt(effects += x).unit)(_ => Task.attempt(effects += x).unit)

val testCase = {
val managed: ZManaged[Any, Throwable, Unit] = res(1).toManagedZIO
Expand All @@ -222,7 +223,7 @@ object CatsZManagedSyntaxSpec extends CatsRunnableSpec {

val effects = new mutable.ListBuffer[Int]
def res(x: Int): Resource[Task, Unit] =
Resource.make(Task(effects += x).unit)(_ => Task(effects += x).unit)
Resource.make(Task.attempt(effects += x).unit)(_ => Task.attempt(effects += x).unit)

def man(x: Int): ZManaged[Any, Throwable, Unit] =
ZManaged.acquireReleaseWith(ZIO.succeed(effects += x).unit)(_ => ZIO.succeed(effects += x))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import cats.effect.unsafe.IORuntime
import cats.laws.discipline.*
import zio.{ durationInt => _, _ }
import zio.interop.catz.*
import zio.managed.*

import scala.concurrent.duration._

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import org.scalatest.prop.Configuration
import org.typelevel.discipline.Laws
import org.typelevel.discipline.scalatest.FunSuiteDiscipline
import zio.*
import zio.managed.*

import java.time.{ Instant, LocalDateTime, OffsetDateTime, ZoneOffset }
import java.util.concurrent.TimeUnit
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package zio.interop

import org.scalacheck.*
import zio.*
import zio.managed.*

/**
* Temporary fork of zio.GenIO that overrides `genParallel` with ZManaged-based code
Expand All @@ -19,7 +20,7 @@ trait GenIOInteropCats {
* Given a generator for `A`, produces a generator for `IO[E, A]` using the `IO.async` constructor.
*/
def genAsyncSuccess[E, A: Arbitrary]: Gen[IO[E, A]] =
Arbitrary.arbitrary[A].map(a => IO.async[E, A](k => k(IO.succeed(a))))
Arbitrary.arbitrary[A].map(a => IO.async[Any, E, A](k => k(IO.succeed(a))))

/**
* Randomly uses either `genSyncSuccess` or `genAsyncSuccess` with equal probability.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package zio.interop

import org.scalacheck.{ Arbitrary, Cogen, Gen }
import zio.*
import zio.managed.*

private[interop] trait ZioSpecBase extends CatsSpecBase with ZioSpecBaseLowPriority with GenIOInteropCats {

Expand Down
4 changes: 2 additions & 2 deletions zio-interop-cats/shared/src/main/scala/zio/interop/CHub.scala
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ package zio.interop

import cats.effect.kernel.{ Async, Resource }
import cats.effect.std.Dispatcher
import zio.interop.catz.zManagedSyntax
import zio.interop.catz.scopedSyntax
import zio.{ Runtime, ZDequeue, ZEnqueue, ZHub, ZQueue, ZTraceElement }

/**
Expand Down Expand Up @@ -202,7 +202,7 @@ object CHub {
def size(implicit trace: ZTraceElement): F[Int] =
hub.size.toEffect[F]
def subscribe(implicit trace: ZTraceElement): Resource[F, Dequeue[F, B]] =
hub.subscribe.map(Dequeue[F, B](_)).toResource[F]
Resource.scoped[F, Any, Dequeue[F, B]](hub.subscribe.map(Dequeue[F, B](_)))
def contramap[C](f: C => A): CHub[F, C, B] =
CHub(hub.contramap(f))
def contramapM[C](f: C => F[A]): CHub[F, C, B] =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@ import cats.*
import cats.effect.*
import cats.effect.std.Dispatcher
import cats.kernel.{ CommutativeMonoid, CommutativeSemigroup }
import zio.ZManaged.ReleaseMap
import zio.ZTraceElement
import zio.interop.catz.concurrentInstance
import zio.internal.stacktracer.InteropTracer
import zio.internal.stacktracer.{ Tracer => CoreTracer }
import zio.managed.*

trait CatsZManagedSyntax {
import scala.language.implicitConversions
Expand All @@ -41,6 +41,8 @@ trait CatsZManagedSyntax {
implicit final def zManagedSyntax[R, E, A](managed: ZManaged[R, E, A]): ZManagedSyntax[R, E, A] =
new ZManagedSyntax(managed)

implicit final def scopedSyntax(resource: Resource.type): ScopedSyntax =
new ScopedSyntax(resource)
}

final class CatsIOResourceSyntax[F[_], A](private val resource: Resource[F, A]) extends AnyVal {
Expand All @@ -56,55 +58,85 @@ final class ZIOResourceSyntax[R, E <: Throwable, A](private val resource: Resour
* Convert a cats Resource into a ZManaged.
* Beware that unhandled error during release of the resource will result in the fiber dying.
*/
def toManagedZIO(implicit trace: ZTraceElement): ZManaged[R, E, A] = {
def toManagedZIO(implicit trace: ZTraceElement): ZManaged[R, E, A] =
ZManaged.scoped[R](toScopedZIO)

/**
* Convert a cats Resource into a scoped ZIO.
* Beware that unhandled error during release of the resource will result in the fiber dying.
*/
def toScopedZIO(implicit trace: ZTraceElement): ZIO[R with Scope, E, A] = {
type F[T] = ZIO[R, E, T]
val F = MonadCancel[F, E]

def go[B](resource: Resource[F, B]): ZManaged[R, E, B] =
def go[B](resource: Resource[F, B]): ZIO[R with Scope, E, B] =
resource match {
case allocate: Resource.Allocate[F, b] =>
ZManaged.fromReservationZIO[R, E, B](F.uncancelable(allocate.resource).map { case (b, release) =>
Reservation(ZIO.succeedNow(b), error => release(toExitCase(error)).orDie)
})
ZIO.acquireReleaseExit {
F.uncancelable(allocate.resource)
} { case ((_, release), exit) =>
release(toExitCase(exit)).orDie
}.map(_._1)

case bind: Resource.Bind[F, a, B] =>
go(bind.source).flatMap(a => go(bind.fs(a)))

case eval: Resource.Eval[F, b] =>
ZManaged.fromZIO(eval.fa)
eval.fa

case pure: Resource.Pure[F, B] =>
ZManaged.succeedNow(pure.a)
ZIO.succeedNow(pure.a)
}

go(resource)
}
}

final class ZManagedSyntax[R, E, A](private val managed: ZManaged[R, E, A]) extends AnyVal {
def toResourceZIO(implicit trace: ZTraceElement): Resource[ZIO[R, E, _], A] = {
import zio.interop.catz.scopedSyntax

def toResourceZIO(implicit trace: ZTraceElement): Resource[ZIO[R, E, _], A] =
Resource.scopedZIO[R, E, A](scoped(managed))

def toResource[F[_]: Async](implicit R: Runtime[R], ev: E <:< Throwable, trace: ZTraceElement): Resource[F, A] =
Resource.scoped[F, R, A](scoped(managed).mapError(ev))

private def scoped[R, E, A](managed: ZManaged[R, E, A])(implicit trace: ZTraceElement): ZIO[R with Scope, E, A] =
for {
scope <- ZIO.scope
releaseMap <- ZManaged.ReleaseMap.make
_ <- scope.addFinalizerExit(releaseMap.releaseAll(_, ExecutionStrategy.Sequential))
tuple <- ZManaged.currentReleaseMap.locally(releaseMap)(managed.zio)
(_, a) = tuple
} yield a
}

final class ScopedSyntax(private val self: Resource.type) extends AnyVal {
def scopedZIO[R, E, A](zio: ZIO[Scope with R, E, A])(implicit trace: ZTraceElement): Resource[ZIO[R, E, _], A] = {
type F[T] = ZIO[R, E, T]

Resource
.applyCase[F, ReleaseMap](
ZManaged.ReleaseMap.make.map { releaseMap =>
(releaseMap, exitCase => releaseMap.releaseAll(toExit(exitCase), ExecutionStrategy.Sequential).unit)
.applyCase[F, Scope.Closeable](
Scope.make.map { scope =>
(scope, exitCase => scope.close(toExit(exitCase)))
}
)
.flatMap { releaseMap =>
.flatMap { scope =>
Resource.suspend(
ZManaged.currentReleaseMap.locally(releaseMap) {
managed.zio.map { case (_, a) =>
scope.extend[R] {
zio.map { case a =>
Resource.applyCase[F, A](ZIO.succeedNow((a, _ => ZIO.unit)))
}
}
)
}
}

def toResource[F[_]: Async](implicit R: Runtime[R], ev: E <:< Throwable, trace: ZTraceElement): Resource[F, A] =
toResourceZIO.mapK(new (ZIO[R, E, _] ~> F) {
override def apply[B](zio: ZIO[R, E, B]) = toEffect(zio.mapError(ev))
def scoped[F[_]: Async, R, A](
zio: ZIO[Scope with R, Throwable, A]
)(implicit runtime: Runtime[R], trace: ZTraceElement): Resource[F, A] =
scopedZIO[R, Throwable, A](zio).mapK(new (ZIO[R, Throwable, _] ~> F) {
override def apply[B](zio: ZIO[R, Throwable, B]) = toEffect(zio)
})
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ final class TSemaphore[F[+_]] private (underlying: ZTSemaphore) {
* See [[zio.stm.TSemaphore#withPermitsManaged]]
*/
def withPermitsResource(n: Long)(implicit R: Runtime[Any], F: Async[F], trace: ZTraceElement): Resource[F, Unit] =
underlying.withPermitsManaged(n).toResource[F]
Resource.scoped(underlying.withPermitsScoped(n))
}

object TSemaphore {
Expand Down
Loading

0 comments on commit 5e028e9

Please sign in to comment.