-
Notifications
You must be signed in to change notification settings - Fork 918
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
Add a build method to ServerListener
responsible for graceful termination of an external Executor
.
#5087
Add a build method to ServerListener
responsible for graceful termination of an external Executor
.
#5087
Conversation
1. Add `withExecutor` method to `ServerListener`. 2. Add `stoppingWithExecutor` method to `ServerListenerBuilder`. 3. Extended `ShutdownSupport` methods with time-limited termination and customized termination logic. 4. Added tests for `ServerListener`.
bea5b90
to
cec892b
Compare
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.
I have left a review while extending the existing ShutdownSupport#of
method. I would appreciate it if you could check the following points.
FYI, I implemented the graceful shutdown logic based on the ExecutorService
's javadoc.
core/src/main/java/com/linecorp/armeria/server/ShutdownSupport.java
Outdated
Show resolved
Hide resolved
core/src/main/java/com/linecorp/armeria/server/ShutdownSupport.java
Outdated
Show resolved
Hide resolved
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.
I added a total of 6 tests, divided into three types of Executor
, depending on whether they wait infinitely or with a finite period:
- Executor that runs periodically every 1 second.
- Executor that runs an infinite loop and can be interrupted.
- Executor that runs an infinite loop and cannot be interrupted.
core/src/test/java/com/linecorp/armeria/server/ServerListenerTest.java
Outdated
Show resolved
Hide resolved
Codecov ReportAttention:
Additional details and impacted files@@ Coverage Diff @@
## main #5087 +/- ##
===========================================
+ Coverage 0 73.94% +73.94%
- Complexity 0 20103 +20103
===========================================
Files 0 1729 +1729
Lines 0 74146 +74146
Branches 0 9465 +9465
===========================================
+ Hits 0 54830 +54830
- Misses 0 14834 +14834
- Partials 0 4482 +4482 ☔ View full report in Codecov by Sentry. |
core/src/main/java/com/linecorp/armeria/server/ServerListener.java
Outdated
Show resolved
Hide resolved
core/src/main/java/com/linecorp/armeria/server/ServerListenerBuilder.java
Outdated
Show resolved
Hide resolved
core/src/main/java/com/linecorp/armeria/server/ServerListenerBuilder.java
Show resolved
Hide resolved
core/src/main/java/com/linecorp/armeria/server/ServerListenerBuilder.java
Outdated
Show resolved
Hide resolved
core/src/main/java/com/linecorp/armeria/server/ServerListenerBuilder.java
Outdated
Show resolved
Hide resolved
core/src/main/java/com/linecorp/armeria/server/ShutdownSupport.java
Outdated
Show resolved
Hide resolved
1. Apply the `@UnstableApi` annotation. 2. Remove the method that receiving customized shutdown logic. 3. Modify the method to accept `terminationTimeoutMillis` as a parameter. 4. Delete `UnstoppableScheduledExecutorService`.
core/src/main/java/com/linecorp/armeria/server/ShutdownSupport.java
Outdated
Show resolved
Hide resolved
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.
Looks good overall 👍 Left some minor comments/questions
core/src/main/java/com/linecorp/armeria/server/ServerListenerBuilder.java
Outdated
Show resolved
Hide resolved
* is stopping. It will wait indefinitely for the {@link ExecutorService} to terminate during shutdown. | ||
*/ | ||
@UnstableApi | ||
public ServerListenerBuilder shutdownWhenStopping(ExecutorService executorService) { |
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.
Question) This is more a question to @ikhoon since the issue seems to suggest this.
AFAIK whenStopping
callbacks are invoked before the server starts shutting down.
If the ExecutorService
is used by the server, I fear that an early cancellation may result in rejected tasks -> failed requests.
Is there a reason we're not adding to whenStopped
instead?
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.
Good question. I think both shutdownWhenStopping()
and shutdownWhenStopped()
are useful.
- If an executor is used for periodic jobs such as updating a server's health, an early stop would be preferred for fast-rolling updates.
- If an executor is used for async execution of incoming requests, lazy stopping would make sense.
How about adding both? :-)
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.
That sounds like a good idea. I've also added shutdownWhenStopped()
.
…arios where external interruptions occur.
…fy the code to wait indefinitely when `terminationTimeout` is set to 0.
ca8dea4
to
675edb4
Compare
core/src/main/java/com/linecorp/armeria/server/ServerListenerBuilder.java
Outdated
Show resolved
Hide resolved
core/src/main/java/com/linecorp/armeria/server/ServerListenerBuilder.java
Outdated
Show resolved
Hide resolved
* is stopping. It will wait indefinitely for the {@link ExecutorService} to terminate during shutdown. | ||
*/ | ||
@UnstableApi | ||
public ServerListenerBuilder shutdownWhenStopping(ExecutorService executorService) { |
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.
Good question. I think both shutdownWhenStopping()
and shutdownWhenStopped()
are useful.
- If an executor is used for periodic jobs such as updating a server's health, an early stop would be preferred for fast-rolling updates.
- If an executor is used for async execution of incoming requests, lazy stopping would make sense.
How about adding both? :-)
core/src/test/java/com/linecorp/armeria/server/ServerListenerTest.java
Outdated
Show resolved
Hide resolved
core/src/test/java/com/linecorp/armeria/server/ServerListenerTest.java
Outdated
Show resolved
Hide resolved
core/src/main/java/com/linecorp/armeria/server/ServerListenerBuilder.java
Outdated
Show resolved
Hide resolved
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.
Looks good overall. Left some suggestions. 😉
core/src/main/java/com/linecorp/armeria/server/ServerListenerBuilder.java
Outdated
Show resolved
Hide resolved
core/src/main/java/com/linecorp/armeria/server/ServerListenerBuilder.java
Outdated
Show resolved
Hide resolved
core/src/main/java/com/linecorp/armeria/server/ServerListenerBuilder.java
Outdated
Show resolved
Hide resolved
core/src/main/java/com/linecorp/armeria/server/ServerListenerBuilder.java
Outdated
Show resolved
Hide resolved
core/src/main/java/com/linecorp/armeria/server/ShutdownSupport.java
Outdated
Show resolved
Hide resolved
.build(); | ||
server.start().get(); | ||
stopFuture = server.stop(); | ||
Thread.sleep(5000); |
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.
Could you reduce these values so that the amount of total build time isn't increased too much?
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.
I combined the 12 divided tests into one to reduce the total test execution time. The tests, which used to take 60 seconds to complete, have now been reduced to 20 seconds.
Note: I attempted to terminate the ExecutorService instances concurrently without waiting for them to shut down sequentially. However, due to Armeria's ServerListener waiting for the synchronous termination of registered listeners, I had no choice but to wait for Executor termination one by one.
…lecting a method based on the `terminationTimeout` value to the `ShutdownSupport.of` method.
05f4471
to
3d58754
Compare
core/src/test/java/com/linecorp/armeria/server/ServerListenerTest.java
Outdated
Show resolved
Hide resolved
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.
Looks great. Thanks! 👍
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.
Looks good, thanks @tomatophobia 🙇 👍 🙇
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.
Thanks, @tomatophobia! 🙇♂️🙇♂️
Motivation:
ServerListener
#5031ExecutorService
to handle background tasks. In such cases, users may want to gracefully shut down theExecutorService
in sync with Armeria's shutdown. To facilitate this, it would be useful to add an API that builds aServerListener
responsible for graceful termination. ThisServerListener
would be able to handle the graceful shutdown of the user's customExecutorService
.Modifications:
stoppingWithExecutor
methods toServerListenerBuilder
.ShutdownSupport#of(ExecutorService, ...)
methods with time-limited termination and customized termination logic.ServerListner#withExecutor
for creating a completeServerListener
.ServerListener
.Result:
ServerListener
#5031ServerListener
that synchronizes the graceful shutdown of their own customExecutorService
with Armeria's shutdown.