scalapb / zio-grpc

ScalaPB meets ZIO: write purely functional gRPC services and clients using ZIO
Apache License 2.0
259 stars 82 forks source link

Resources don't get released #518

Closed omidb closed 1 year ago

omidb commented 1 year ago

I'm creating very simple server and I'm using sbt and the run command to run the server. I can run my server but after interrupting the execution using ctrl+c, I cannot run the server again. It seems that it's not releasing the resources correctly:

timestamp=2023-06-22T19:18:31.257734Z level=ERROR thread=#zio-fiber-1 message="" cause="Exception in thread "zio-fiber-4" java.io.IOException: Failed to bind to address 0.0.0.0/0.0.0.0:9001

and here is the code:

object ConsoleGrpcServer2 extends zio.ZIOAppDefault {

  def welcome: ZIO[Any, Throwable, Unit] =
    printLine("Server is running. Press Ctrl-C to stop ...")

  def createGRPCServer() = {
    def port: Int = 9001
    def services: ServiceList[Any] = ServiceList.add(ConsoleGrpcService)

    def builder =
      ServerBuilder
        .forPort(port)
        .addService(ProtoReflectionService.newInstance())

    def serverLive: ZLayer[Any, Throwable, GServer] =
      ServerLayer.fromServiceList(builder, services)

    serverLive
  }

  val grpcServer = createGRPCServer()

  val myAppLogic = grpcServer.launch // httpServer.zipPar(grpcServer.launch)

  def run = {
    myAppLogic.mapError(t => printLine(t))
    myAppLogic
  }

Should I use a different layer or something?

thesamet commented 1 year ago

Confirming, thanks for reporting. I've noticed this behavior recently and will take a look.

regiskuckaertz commented 1 year ago

Probably this: https://github.com/scalapb/zio-grpc/blob/f932ee9c39ddca40e7675831ff3ace4de18e45c8/core/src/main/scalajvm/scalapb/zio_grpc/Server.scala#L36-L37

needs to change to:

  def toManaged: ZIO[Scope, Throwable, Server] =
    start.as(this).withFinalizer(_ => (this.shutdown *> this.awaitTermination).ignore)
thesamet commented 1 year ago

Thanks for the PR @regiskuckaertz . Agree it is better to wait for shutdown before the program moves on, however the user's issue is caused by SBT.

When running in sbt without fork := true, hitting Ctrl-C will not make the finalizers run - it makes the main thread exit immediately and all background threads remain running. AFAIK, there is no way for a program to handle this interrupt. To solve the problem, you have to add fork := true to your sbt settings.

regiskuckaertz commented 1 year ago

@thesamet ah, I did not catch that part, but indeed that's unrelated to the library. Thanks for merging!