diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index cfe920e147..ecf41b6e80 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -26,7 +26,7 @@ jobs: strategy: matrix: os: [ubuntu-latest] - scala: [2.12.19, 2.13.14, 3.3.3] + scala: [2.12.20, 2.13.16, 3.3.4] java: - graal_graalvm@17 - graal_graalvm@21 @@ -82,8 +82,8 @@ jobs: apps: sbt - name: Check formatting - if: matrix.scala == '2.13.14' - run: sbt ++2.13.14 fmtCheck + if: matrix.scala == '2.13.16' + run: sbt ++2.13.16 fmtCheck - name: Check that workflows are up to date run: sbt '++ ${{ matrix.scala }}' githubWorkflowCheck @@ -94,8 +94,8 @@ jobs: - uses: coursier/setup-action@v1 - name: Test sbt plugin - if: ${{ github.event_name == 'pull_request' }} && matrix.scala == '2.12.19' - run: sbt ++2.12.19 zioHttpGenSbt/scripted + if: ${{ github.event_name == 'pull_request' }} && matrix.scala == '2.12.20' + run: sbt ++2.12.20 zioHttpGenSbt/scripted - uses: coursier/setup-action@v1 with: @@ -103,10 +103,10 @@ jobs: - name: Check doc generation if: ${{ github.event_name == 'pull_request' }} - run: sbt ++2.13.14 doc + run: sbt ++2.13.16 doc - name: zio-http-shaded Tests - if: matrix.scala == '2.13.14' + if: matrix.scala == '2.13.16' env: PUBLISH_SHADED: true run: sbt '++ ${{ matrix.scala }}' zioHttpShadedTests/test @@ -127,7 +127,7 @@ jobs: strategy: matrix: os: [ubuntu-latest] - scala: [2.13.14] + scala: [2.13.16] java: [graal_graalvm@17] runs-on: ${{ matrix.os }} steps: @@ -172,32 +172,32 @@ jobs: java-version: 21 cache: sbt - - name: Download target directories (2.12.19) + - name: Download target directories (2.12.20) uses: actions/download-artifact@v4 with: - name: target-${{ matrix.os }}-2.12.19-${{ matrix.java }} + name: target-${{ matrix.os }}-2.12.20-${{ matrix.java }} - - name: Inflate target directories (2.12.19) + - name: Inflate target directories (2.12.20) run: | tar xf targets.tar rm targets.tar - - name: Download target directories (2.13.14) + - name: Download target directories (2.13.16) uses: actions/download-artifact@v4 with: - name: target-${{ matrix.os }}-2.13.14-${{ matrix.java }} + name: target-${{ matrix.os }}-2.13.16-${{ matrix.java }} - - name: Inflate target directories (2.13.14) + - name: Inflate target directories (2.13.16) run: | tar xf targets.tar rm targets.tar - - name: Download target directories (3.3.3) + - name: Download target directories (3.3.4) uses: actions/download-artifact@v4 with: - name: target-${{ matrix.os }}-3.3.3-${{ matrix.java }} + name: target-${{ matrix.os }}-3.3.4-${{ matrix.java }} - - name: Inflate target directories (3.3.3) + - name: Inflate target directories (3.3.4) run: | tar xf targets.tar rm targets.tar @@ -266,7 +266,7 @@ jobs: strategy: matrix: os: [ubuntu-latest] - scala: [2.13.14] + scala: [2.13.16] java: [temurin@8] runs-on: ${{ matrix.os }} steps: @@ -302,7 +302,7 @@ jobs: strategy: matrix: os: [ubuntu-latest] - scala: [2.13.14] + scala: [2.13.16] java: [temurin@8] runs-on: ${{ matrix.os }} steps: @@ -340,7 +340,7 @@ jobs: strategy: matrix: os: [ubuntu-latest] - scala: [2.13.14] + scala: [2.13.16] java: [temurin@8] runs-on: ${{ matrix.os }} steps: @@ -378,7 +378,7 @@ jobs: strategy: matrix: os: [ubuntu-latest] - scala: [2.13.14] + scala: [2.13.16] java: [temurin@8] runs-on: ${{ matrix.os }} steps: @@ -416,7 +416,7 @@ jobs: strategy: matrix: os: [ubuntu-latest] - scala: [2.13.14] + scala: [2.13.16] java: [temurin@8] runs-on: ${{ matrix.os }} steps: @@ -454,7 +454,7 @@ jobs: strategy: matrix: os: [ubuntu-latest] - scala: [2.13.14] + scala: [2.13.16] java: [temurin@8] runs-on: ${{ matrix.os }} steps: @@ -492,7 +492,7 @@ jobs: strategy: matrix: os: [ubuntu-latest] - scala: [2.13.14] + scala: [2.13.16] java: [temurin@8] runs-on: ${{ matrix.os }} steps: @@ -530,7 +530,7 @@ jobs: strategy: matrix: os: [ubuntu-latest] - scala: [2.13.14] + scala: [2.13.16] java: [temurin@8] runs-on: ${{ matrix.os }} steps: @@ -568,7 +568,7 @@ jobs: strategy: matrix: os: [ubuntu-latest] - scala: [2.13.14] + scala: [2.13.16] java: [temurin@8] runs-on: ${{ matrix.os }} steps: @@ -606,7 +606,7 @@ jobs: strategy: matrix: os: [ubuntu-latest] - scala: [2.13.14] + scala: [2.13.16] java: [temurin@8] runs-on: ${{ matrix.os }} steps: @@ -644,7 +644,7 @@ jobs: strategy: matrix: os: [ubuntu-latest] - scala: [2.13.14] + scala: [2.13.16] java: [temurin@8] runs-on: ${{ matrix.os }} steps: @@ -682,7 +682,7 @@ jobs: strategy: matrix: os: [ubuntu-latest] - scala: [2.13.14] + scala: [2.13.16] java: [temurin@8] runs-on: ${{ matrix.os }} steps: @@ -720,7 +720,7 @@ jobs: strategy: matrix: os: [ubuntu-latest] - scala: [2.13.14] + scala: [2.13.16] java: [temurin@8] runs-on: ${{ matrix.os }} steps: @@ -872,7 +872,7 @@ jobs: strategy: matrix: os: [ubuntu-latest] - scala: [2.13.14] + scala: [2.13.16] java: [temurin@8] runs-on: ${{ matrix.os }} steps: @@ -951,7 +951,7 @@ jobs: strategy: matrix: os: [ubuntu-latest] - scala: [2.13.14] + scala: [2.13.16] java: [temurin@8] runs-on: ${{ matrix.os }} steps: diff --git a/project/BuildHelper.scala b/project/BuildHelper.scala index 62b15549b1..fdafde0b3b 100644 --- a/project/BuildHelper.scala +++ b/project/BuildHelper.scala @@ -6,9 +6,9 @@ import xerial.sbt.Sonatype.autoImport.* import sbtcrossproject.CrossPlugin.autoImport.crossProjectPlatform object BuildHelper extends ScalaSettings { - val Scala212 = "2.12.19" - val Scala213 = "2.13.14" - val Scala3 = "3.3.3" + val Scala212 = "2.12.20" + val Scala213 = "2.13.15" + val Scala3 = "3.3.4" val ScoverageVersion = "2.0.12" val JmhVersion = "0.4.7" diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 267b6f5c21..da3bd55f3c 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -5,7 +5,7 @@ object Dependencies { val NettyVersion = "4.1.116.Final" val NettyIncubatorVersion = "0.0.25.Final" val ScalaCompactCollectionVersion = "2.12.0" - val ZioVersion = "2.1.11" + val ZioVersion = "2.1.14" val ZioCliVersion = "0.5.0" val ZioJsonVersion = "0.7.1" val ZioParserVersion = "0.1.10" diff --git a/project/plugins.sbt b/project/plugins.sbt index 737041f101..8af554dbe8 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -10,7 +10,7 @@ addSbtPlugin("de.heikoseeberger" % "sbt-header" % "5.10.0") addSbtPlugin("org.scoverage" % "sbt-scoverage" % "2.0.12") addSbtPlugin("io.get-coursier" % "sbt-shading" % "2.1.4") addSbtPlugin("com.github.cb372" % "sbt-explicit-dependencies" % "0.3.1") -addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.16.0") +addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.18.1") addSbtPlugin("org.portable-scala" % "sbt-scalajs-crossproject" % "1.3.2") addSbtPlugin("com.thesamet" % "sbt-protoc" % "1.0.7") addSbtPlugin("com.thesamet" % "sbt-protoc-gen-project" % "0.1.8") diff --git a/zio-http-testkit/src/main/scala/zio/http/TestServer.scala b/zio-http-testkit/src/main/scala/zio/http/TestServer.scala index d551f693dd..0dd0558c36 100644 --- a/zio-http-testkit/src/main/scala/zio/http/TestServer.scala +++ b/zio-http-testkit/src/main/scala/zio/http/TestServer.scala @@ -98,7 +98,7 @@ final case class TestServer(driver: Driver, bindPort: Int) extends Server { _ <- driver.addApp(provided, r) } yield () - override def install[R](routes: Routes[R, Response])(implicit + override def install[R](routes: Routes[Scope & R, Response])(implicit trace: zio.Trace, tag: EnvironmentTag[R], ): URIO[R, Unit] = diff --git a/zio-http/jvm/src/main/scala/zio/http/netty/NettyBody.scala b/zio-http/jvm/src/main/scala/zio/http/netty/NettyBody.scala index c5ba490efa..e66416e71d 100644 --- a/zio-http/jvm/src/main/scala/zio/http/netty/NettyBody.scala +++ b/zio-http/jvm/src/main/scala/zio/http/netty/NettyBody.scala @@ -161,7 +161,7 @@ object NettyBody extends BodyEncoding { lazy val loop: ZChannel[Any, Any, Any, Any, E, Chunk[A], Unit] = ZChannel.unwrap( queue.take - .flatMap(_.done) + .flatMap(_.exit) .fold( maybeError => ZChannel.fromZIO(queue.shutdown) *> diff --git a/zio-http/jvm/src/main/scala/zio/http/netty/server/NettyDriver.scala b/zio-http/jvm/src/main/scala/zio/http/netty/server/NettyDriver.scala index 334b186711..1565b764ee 100644 --- a/zio-http/jvm/src/main/scala/zio/http/netty/server/NettyDriver.scala +++ b/zio-http/jvm/src/main/scala/zio/http/netty/server/NettyDriver.scala @@ -61,7 +61,7 @@ private[zio] final case class NettyDriver( ) } yield StartResult(port, serverInboundHandler.inFlightRequests) - def addApp[R](newApp: Routes[R, Response], env: ZEnvironment[R])(implicit trace: Trace): UIO[Unit] = + override def addApp[R](newApp: Routes[Scope & R, Response], env: ZEnvironment[R])(implicit trace: Trace): UIO[Unit] = ZIO.fiberId.map { fiberId => var loop = true while (loop) { diff --git a/zio-http/jvm/src/main/scala/zio/http/netty/server/ServerInboundHandler.scala b/zio-http/jvm/src/main/scala/zio/http/netty/server/ServerInboundHandler.scala index 74340d825e..fd181db1e0 100644 --- a/zio-http/jvm/src/main/scala/zio/http/netty/server/ServerInboundHandler.scala +++ b/zio-http/jvm/src/main/scala/zio/http/netty/server/ServerInboundHandler.scala @@ -92,7 +92,8 @@ private[zio] final case class ServerInboundHandler( if (attemptImmediateWrite(ctx, req.method, exit)) { releaseRequest() } else { - writeResponse(ctx, runtime, exit, req)(releaseRequest) + val scope = Scope.unsafe.make + writeResponse(ctx, runtime, scope.use(exit), req)(releaseRequest) } } } finally { diff --git a/zio-http/jvm/src/test/scala/zio/http/ServerRuntimeSpec.scala b/zio-http/jvm/src/test/scala/zio/http/ServerRuntimeSpec.scala index 91aa54f2a5..518e8fb485 100644 --- a/zio-http/jvm/src/test/scala/zio/http/ServerRuntimeSpec.scala +++ b/zio-http/jvm/src/test/scala/zio/http/ServerRuntimeSpec.scala @@ -75,10 +75,23 @@ object ServerRuntimeSpec extends RoutesRunnableSpec { .scoped(serve[Foo](server)) .zipRight(server.deploy.body.run(path = Path.root / "test", method = Method.GET)) .flatMap(_.asString(Charsets.Utf8)) - .map(b => assertTrue(b == "1")) + .map(b => assertTrue(b == "2")) // one extra for Scope + } + + test("with scope") { + val ref = Ref.unsafe.make(0)(zio.Unsafe) + val routes = Routes( + Method.GET / "test" -> handler( + ZIO.addFinalizer(ref.set(1)).as(Response.text("ok")), + ), + ) + serve(routes) + .zipRight(routes.deploy.body.run(path = Path.root / "test", method = Method.GET)) + .flatMap(_.asString(Charsets.Utf8)) + .map(b => assertTrue(b == "ok")) *> ref.get.map { v => assertTrue(v == 1) } } } .provide( + Scope.default, DynamicServer.live, Server.customized, ZLayer.succeed(Server.Config.default), diff --git a/zio-http/jvm/src/test/scala/zio/http/internal/RoutesRunnableSpec.scala b/zio-http/jvm/src/test/scala/zio/http/internal/RoutesRunnableSpec.scala index 9e452dcb09..72d141c87a 100644 --- a/zio-http/jvm/src/test/scala/zio/http/internal/RoutesRunnableSpec.scala +++ b/zio-http/jvm/src/test/scala/zio/http/internal/RoutesRunnableSpec.scala @@ -16,7 +16,7 @@ package zio.http.internal -import zio.{EnvironmentTag, Scope, ZIO} +import zio.{&, EnvironmentTag, Scope, ZIO} import zio.http.URL.Location import zio.http._ @@ -111,7 +111,9 @@ abstract class RoutesRunnableSpec extends ZIOHttpSpec { self => _ <- DynamicServer.setStart(server) } yield port - def serve[R: EnvironmentTag](routes: Routes[R, Response]): ZIO[R with DynamicServer with Server, Nothing, Int] = + def serve[R: EnvironmentTag]( + routes: Routes[Scope & R, Response], + ): ZIO[R with DynamicServer with Server, Nothing, Int] = for { server <- ZIO.service[Server] port <- Server.install(routes) diff --git a/zio-http/shared/src/main/scala/zio/http/Driver.scala b/zio-http/shared/src/main/scala/zio/http/Driver.scala index 0787c90658..4b6b1d3e05 100644 --- a/zio-http/shared/src/main/scala/zio/http/Driver.scala +++ b/zio-http/shared/src/main/scala/zio/http/Driver.scala @@ -26,7 +26,7 @@ import zio.http.Driver.StartResult trait Driver { def start(implicit trace: Trace): RIO[Scope, StartResult] - def addApp[R](newRoutes: Routes[R, Response], env: ZEnvironment[R])(implicit trace: Trace): UIO[Unit] + def addApp[R](newRoutes: Routes[Scope & R, Response], env: ZEnvironment[R])(implicit trace: Trace): UIO[Unit] def createClientDriver()(implicit trace: Trace): ZIO[Scope, Throwable, ClientDriver] } diff --git a/zio-http/shared/src/main/scala/zio/http/Server.scala b/zio-http/shared/src/main/scala/zio/http/Server.scala index b1522afc29..2e63adc5e1 100644 --- a/zio-http/shared/src/main/scala/zio/http/Server.scala +++ b/zio-http/shared/src/main/scala/zio/http/Server.scala @@ -32,7 +32,7 @@ trait Server { /** * Installs the given HTTP application into the server. */ - def install[R](routes: Routes[R, Response])(implicit trace: Trace, tag: EnvironmentTag[R]): URIO[R, Unit] + def install[R](routes: Routes[Scope & R, Response])(implicit trace: Trace, tag: EnvironmentTag[R]): URIO[R, Unit] /** * The port on which the server is listening. @@ -435,7 +435,7 @@ object Server extends ServerPlatformSpecific { } def serve[R]( - routes: Routes[R, Response], + routes: Routes[Scope & R, Response], )(implicit trace: Trace, tag: EnvironmentTag[R]): URIO[R with Server, Nothing] = { ZIO.logInfo("Starting the server...") *> ZIO.serviceWithZIO[Server](_.install[R](routes)) *> @@ -444,14 +444,14 @@ object Server extends ServerPlatformSpecific { } def serve[R]( - route: Route[R, Response], - routes: Route[R, Response]*, + route: Route[Scope & R, Response], + routes: Route[Scope & R, Response]*, )(implicit trace: Trace, tag: EnvironmentTag[R]): URIO[R with Server, Nothing] = { serve(Routes(route, routes: _*)) } def install[R]( - routes: Routes[R, Response], + routes: Routes[Scope & R, Response], )(implicit trace: Trace, tag: EnvironmentTag[R]): URIO[R with Server, Int] = { ZIO.serviceWithZIO[Server](_.install[R](routes)) *> ZIO.serviceWithZIO[Server](_.port) } @@ -523,7 +523,7 @@ object Server extends ServerPlatformSpecific { // or a throwable if starting the driver failed for any reason. private val serverStarted: Promise[Throwable, Int], ) extends Server { - override def install[R](routes: Routes[R, Response])(implicit + override def install[R](routes: Routes[Scope & R, Response])(implicit trace: Trace, tag: EnvironmentTag[R], ): URIO[R, Unit] = diff --git a/zio-http/shared/src/main/scala/zio/http/endpoint/Endpoint.scala b/zio-http/shared/src/main/scala/zio/http/endpoint/Endpoint.scala index 3eab47c46c..7cd0603713 100644 --- a/zio-http/shared/src/main/scala/zio/http/endpoint/Endpoint.scala +++ b/zio-http/shared/src/main/scala/zio/http/endpoint/Endpoint.scala @@ -233,22 +233,22 @@ final case class Endpoint[PathInput, Input, Err, Output, Auth <: AuthType]( def implementEither(f: Input => Either[Err, Output])(implicit trace: Trace, ): Route[Any, Nothing] = - implementHandler[Any](Handler.fromFunctionHandler[Input](in => Handler.fromEither(f(in)))) + implementHandler[Any](Handler.fromFunctionEither[Input](f)) def implementPurely(f: Input => Output)(implicit trace: Trace, ): Route[Any, Nothing] = - implementHandler[Any](Handler.fromFunctionHandler[Input](in => Handler.succeed(f(in)))) + implementHandler[Any](Handler.fromFunctionExit[Input](in => Exit.succeed(f(in)))) def implementAs(output: Output)(implicit trace: Trace, ): Route[Any, Nothing] = implementHandler[Any](Handler.succeed(output)) - def implementAsZIO(output: ZIO[Any, Err, Output])(implicit + def implementAsZIO[Env](output: ZIO[Env, Err, Output])(implicit trace: Trace, - ): Route[Any, Nothing] = - implementHandler[Any](Handler.fromZIO(output)) + ): Route[Env, Nothing] = + implementHandler(Handler.fromZIO(output)) def implementAsError(err: Err)(implicit trace: Trace,