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

Netty executor leaking outside zio-http #1896

Closed
ghostdogpr opened this issue Dec 29, 2022 · 22 comments · Fixed by #1959 or zio/zio#7787
Closed

Netty executor leaking outside zio-http #1896

ghostdogpr opened this issue Dec 29, 2022 · 22 comments · Fixed by #1959 or zio/zio#7787
Labels
bug Something isn't working

Comments

@ghostdogpr
Copy link
Member

We have test failures with RejectedExecutionException in Caliban when upgrading to the latest version of zio-http (0.0.3).

What happens is that we have some tests that start a zio-http server. I noticed that zio-http creates its own executor and calls onExecutor to override the default (see usingSharedThreadPool in NettyRuntime). The problem is that when the test ends, this executor gets closed when the server's ZLayer is terminated, but the zio runtime attempts at running more things on this executor afterwards (in our case, interrupting something in TestClock), triggering the RejectedExecutionException. It looks as if the executor leaks outside of its intended scope. Any idea about this?

@soujiro32167
Copy link
Contributor

Is this the cause of the

Exception in thread "zio-fiber-22" java.util.concurrent.RejectedExecutionException: Unable to run zio.internal.FiberRuntime@34b068e2
  	at zio.test.TestClock.default(TestClock.scala:408)

I've seen since upgrading?

@frekw
Copy link
Contributor

frekw commented Jan 2, 2023

@soujiro32167 yes, or at least that's what we're seeing in Caliban's tests as well.

@soujiro32167
Copy link
Contributor

Thanks for confirming @frekw I was going nuts!

@soujiro32167
Copy link
Contributor

I was able to mitigate by changing the netty pool to a dedicated one:

  // TODO: remove this when https://github.com/zio/zio-http/issues/1896 is fixed
  val driver = ZLayer.scoped {
    val app = ZLayer.succeed(
      new AtomicReference[(HttpApp[Any, Throwable], ZEnvironment[Any])]((Http.empty, ZEnvironment.empty)),
    )
    val ecb = ZLayer.succeed(new AtomicReference[Option[Server.ErrorCallback]](Option.empty))
    val time = ZLayer.succeed(ServerTime.make(1000 millis))

    val serverChannelFactory: ZLayer[ServerConfig, Nothing, ChannelFactory[ServerChannel]] =
      ChannelFactories.Server.fromConfig
    val eventLoopGroup = EventLoopGroups.fromConfig
    val nettyRuntime = NettyRuntime.usingDedicatedThreadPool // the magic is here
    val serverChannelInitializer =
      ServerChannelInitializer.layer
    val serverInboundHandler = ServerInboundHandler.layer

    val serverLayers = app ++
      serverChannelFactory ++
      (
        (
          (time ++ app ++ ecb) ++
            (eventLoopGroup >>> nettyRuntime) >>> serverInboundHandler
          ) >>> serverChannelInitializer
        ) ++
      ecb ++
      eventLoopGroup

    make
      .provideSome[ServerConfig & Scope](
        serverLayers,
      )

  }

  val randomPortServer =
    ZLayer.fromZIO(
      zio.Random.RandomLive.nextIntBetween(1024, 65535)
      .map(p => ServerConfig.default.port(p))
    ) >>> driver >>> Server.base

@vigoo
Copy link
Contributor

vigoo commented Jan 25, 2023

@ghostdogpr can you check if my fix above solves your problem?

@ghostdogpr
Copy link
Member Author

I tried but I can't test because we're using zio-http through Tapir and there are many breaking changes so they're not binary compatible. I'll need tapir to be upgraded as well in order to test.

@vigoo
Copy link
Contributor

vigoo commented Jan 25, 2023

Ok then let's get back to this once we have a new release and a compatible tapir. Hopefully it's fixed!

@frekw
Copy link
Contributor

frekw commented Jan 25, 2023

I'll work to get Tapir updated as soon as we have a new release of zio-http!

@frekw
Copy link
Contributor

frekw commented Jan 25, 2023

(with that said, maybe we can cut a 0.0.4 soon to get the new Http changes? :) )

@vigoo
Copy link
Contributor

vigoo commented Jan 25, 2023

(with that said, maybe we can cut a 0.0.4 soon to get the new Http changes? :) )

@jdegoes ? :)

@jdegoes
Copy link
Member

jdegoes commented Jan 25, 2023

@vigoo Yes, let's get your latest round of changes in and do 0.0.4!

@frekw
Copy link
Contributor

frekw commented Jan 27, 2023

Ok, here we go: softwaremill/tapir#2702

Hopefully we can get a snapshot soon and verify if it fixes the issue 🤞

@frekw
Copy link
Contributor

frekw commented Jan 27, 2023

Unfortunately seems like this didn't fix it: ghostdogpr/caliban#1521 :/

@frekw
Copy link
Contributor

frekw commented Jan 27, 2023

Also, @soujiro32167:s workaround to use a dedicated threadpool doesn't really work since NettyRuntime is private[zio].

@frekw
Copy link
Contributor

frekw commented Jan 30, 2023

@vigoo do you want to re-open this or should we submit it as a new issue?

@vigoo vigoo reopened this Jan 30, 2023
@vigoo
Copy link
Contributor

vigoo commented Jan 30, 2023

Reopened, I will take another look! Thanks for trying out

@soujiro32167
Copy link
Contributor

@frekw the object and the usingDedicatedThreadPool function are not private
image

@frekw
Copy link
Contributor

frekw commented Feb 1, 2023

@soujiro32167
Copy link
Contributor

Nooooo

@frekw
Copy link
Contributor

frekw commented Feb 4, 2023

I've managed to produce a minimal test that reproduces the behaviour, so at least now it should be easier to verify: https://github.com/zio/zio-http/pull/1978/files

If you remove the timeoutFail aspect it passes as expected.

@frekw
Copy link
Contributor

frekw commented Feb 4, 2023

Managed to reduce it slightly more so my previous comment is out of date.

Just doing raceFirst with anything that touches zio.Clock seems to cause the error!

@adamgfraser
Copy link
Contributor

Will take a look at this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
6 participants