-
Notifications
You must be signed in to change notification settings - Fork 422
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
Support graceful shutdown in Netty server #3294
Conversation
@@ -2044,7 +2044,8 @@ lazy val examples: ProjectMatrix = (projectMatrix in file("examples")) | |||
scalaTest.value | |||
), | |||
libraryDependencies ++= loggerDependencies, | |||
publishArtifact := false | |||
publishArtifact := false, | |||
Compile / run / fork := true |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is that temporary for development or a new requirement?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is useful for development, when one wants to run examples with examples/runMain a.b.c.HelloExample
and terminate a running server.
doc/server/netty.md
Outdated
@@ -63,6 +63,21 @@ NettyFutureServer(NettyFutureServerOptions.customiseInterceptors.serverLog(None) | |||
NettyFutureServer(NettyConfig.defaultNoStreaming.socketBacklog(256)) | |||
``` | |||
|
|||
## Graceful shutdown | |||
|
|||
A Netty server has to be properly closed using function `NettyFutureServerBinding.stop()` (and analogous functions available in Cats and ZIO bindings). This function ensures that the server will wait at most 10 seconds for in-flight requests to complete, while rejecting all new requests with 503 during this period. Afterwards, it closes all server resources. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
has -> should? you can still just kill the server ...
/** Exposes additional `stop` effect, which allows stopping the server inside your test. It will be called after the test anyway (assuming | ||
* idempotency), but may be useful for some cases where tests need to check specific behavior like returning 503s during shutdown. | ||
*/ | ||
def serverWithStop(routes: NonEmptyList[ROUTE], gracefulShutdownTimeout: Option[FiniteDuration] = None): Resource[IO, (Port, IO[Unit])] = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe that's for a subsequent PR, but maybe it would make sense ot leave this as the only method that has to be implemented by specific test server interpreters? Then server
can be implemented in terms of this function, by dropping the second element of the typle
|
||
class ServerGracefulShutdownTests[F[_], OPTIONS, ROUTE](createServerTest: CreateServerTest[F, Any, OPTIONS, ROUTE])(implicit | ||
m: MonadError[F], | ||
sleeper: Sleeper[F] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe this can be a normal parameter?
def testServer(name: String, rs: => NonEmptyList[ROUTE])( | ||
runTest: (SttpBackend[IO, Fs2Streams[IO] with WebSockets], Uri) => IO[Assertion] | ||
): Test | ||
|
||
def testServerWithStop(name: String, rs: => NonEmptyList[ROUTE], gracefulShutdownTimeout: Option[FiniteDuration])( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
similarly here ... maybe we can reduce the number of variants here by just supporting the stop-variants, and the others would delegate here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
are these used in fact? :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ah ok they are ... still seems we might have to many similar variants, making this hard to understand
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I didn't want to mess up other servers, so I thought to make the default implementation implement testServerWithStop
in terms of testServer
. I'll add some scaladoc to make it less confusing for now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice work! :) Some organizational comments inline
@@ -63,6 +63,21 @@ NettyFutureServer(NettyFutureServerOptions.customiseInterceptors.serverLog(None) | |||
NettyFutureServer(NettyConfig.defaultNoStreaming.socketBacklog(256)) | |||
``` | |||
|
|||
## Graceful shutdown | |||
|
|||
A Netty should can be gracefully closed using function `NettyFutureServerBinding.stop()` (and analogous functions available in Cats and ZIO bindings). This function ensures that the server will wait at most 10 seconds for in-flight requests to complete, while rejecting all new requests with 503 during this period. Afterwards, it closes all server resources. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should can? ;) maybe just run it through chatgpt to iron out the english :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's merge - and maybe you could try to see if the test infrastructure could be somehow simplified? If it's more than 1-2h of effort, probably not worth it
Resolves #3000
This PR enhances Netty server with graceful shutdown.
stop()
from the server bindingNettyConfig
This feature should work with
Future
,ZIO
, andCats Effect
Netty servers.Tests rely heavily on time, so I'm concerned they may be flaky and need some reworks.