Skip to content

Conversation

@novoj
Copy link

@novoj novoj commented Nov 30, 2025

Added parameters to enable setting the quiet period and timeout for graceful shutdown of worker groups, both globally and through the ClientFactoryBuilder.

Make use of graceful shutdown settings on worker groups on the server side.

Refs: #5813

Motivation:

My E2E integration tests are running slowly just because they wait for default graceful shutdown timeout to expire.

Modifications:

  • made use of existing graceful shutdown settings on the server side
  • added new graceful (missing) shutdown settings on the client side

Result:

  • Closes Provide a way to customize the graceful shutdown delay of Netty EventLoopGroups #5813.
  • this pull request has no consequences for the user (#IMHO) - as a default values I configured the defaults that are applied by Netty default implementation
  • user can now explicitly configure zero timeout and quiet period both for server and client side, which results in immediate closing of both and speeding up the termination phase considerably

…`EventLoopGroup`s

Added parameters to enable setting the quiet period and timeout for graceful shutdown of worker groups, both globally and through the `ClientFactoryBuilder`.

Make use of graceful shutdown settings on worker groups on the server side.

Refs: line#5813
@coderabbitai
Copy link

coderabbitai bot commented Nov 30, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

📝 Walkthrough

Walkthrough

Adds configurable quiet-period and timeout settings for Netty worker-group graceful shutdown in the Armeria client: new ClientFactoryBuilder APIs store values in ClientFactoryOptions/Flags, and HttpClientFactory uses those values when calling shutdownGracefully on the worker group.

Changes

Cohort / File(s) Summary
Builder Configuration API
core/src/main/java/com/linecorp/armeria/client/ClientFactoryBuilder.java
Added four public methods to set worker-group graceful shutdown quiet period and timeout (Duration and millis variants). Inputs validated (non-null for Duration, non-negative for millis) and stored into client factory options; methods return ClientFactoryBuilder for chaining.
Options & Accessors
core/src/main/java/com/linecorp/armeria/client/ClientFactoryOptions.java
Added two ClientFactoryOption<Long> constants: WORKER_GROUP_GRACEFUL_SHUTDOWN_QUIET_PERIOD_MILLIS and WORKER_GROUP_GRACEFUL_SHUTDOWN_TIMEOUT_MILLIS, plus instance accessors workerGroupGracefulShutdownQuietPeriodMillis() and workerGroupGracefulShutdownTimeoutMillis().
Shutdown Implementation
core/src/main/java/com/linecorp/armeria/client/HttpClientFactory.java
Replaced no-arg shutdownGracefully() call with shutdownGracefully(quietPeriod, timeout, TimeUnit.MILLISECONDS) using values from options; attaches listener to log failures and complete the close future regardless of outcome.
Default Flag Infrastructure
core/src/main/java/com/linecorp/armeria/common/FlagsProvider.java, core/src/main/java/com/linecorp/armeria/common/DefaultFlagsProvider.java, core/src/main/java/com/linecorp/armeria/common/Flags.java
Introduced two new millis-based default flag accessors: defaultClientWorkerGroupGracefulShutdownQuietPeriodMillis() and defaultClientWorkerGroupGracefulShutdownTimeoutMillis(). Added corresponding default constants and accessors in Flags and DefaultFlagsProvider with validation and @UnstableApi annotations where applicable.

Sequence Diagram(s)

sequenceDiagram
    autonumber
    participant User
    participant Builder as ClientFactoryBuilder
    participant Options as ClientFactoryOptions
    participant Factory as HttpClientFactory
    participant Netty as EventLoopGroup

    User->>Builder: call workerGroupGracefulShutdown*(quiet, timeout)
    Builder->>Options: store WORKER_GROUP_*_MILLIS
    User->>Factory: close()/shutdown client factory
    Factory->>Options: read quietPeriodMillis, timeoutMillis
    Factory->>Netty: shutdownGracefully(quiet, timeout, MILLISECONDS)
    alt shutdown success
        Netty-->>Factory: returns Future success
        Factory-->>User: complete close future
    else shutdown failure
        Netty-->>Factory: returns Future failure
        Factory->>Factory: log warning/error
        Factory-->>User: complete close future
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 Soft paws tap keys to set the clock,

Quiet ticks and timeout on the dock,
Worker hops slow, then gently part,
Builder holds the map and heart,
A graceful close, one tiny hop. ✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 75.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: adding a way to customize graceful shutdown delay for Netty EventLoopGroups.
Description check ✅ Passed The description is clearly related to the changeset, explaining the motivation (speeding up E2E tests), modifications (adding new settings for client-side graceful shutdown), and results.
Linked Issues check ✅ Passed The PR partially addresses issue #5813 by adding client-side graceful shutdown configuration via new methods and options, though it uses a simpler approach (Duration/long parameters) rather than the proposed GracefulShutdownSpec abstraction.
Out of Scope Changes check ✅ Passed All changes are scoped to adding graceful shutdown configuration for worker groups: new builder methods, factory options, flags, and their integration into the shutdown sequence.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

📜 Recent review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 980d851 and 9250fd3.

📒 Files selected for processing (1)
  • core/src/main/java/com/linecorp/armeria/common/FlagsProvider.java
🚧 Files skipped from review as they are similar to previous changes (1)
  • core/src/main/java/com/linecorp/armeria/common/FlagsProvider.java
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Summary

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Nitpick comments (2)
core/src/main/java/com/linecorp/armeria/client/ClientFactoryOptions.java (2)

307-319: Add @UnstableApi annotation to the new public options.

These are newly added public API fields. As per coding guidelines, new public classes and methods should have the @UnstableApi annotation. This applies to these new ClientFactoryOption constants as they are part of the public API surface.

Apply this diff:

     /**
      * The graceful worker group pool quiet period in milliseconds.
      */
+    @UnstableApi
     public static final ClientFactoryOption<Long> WORKER_GROUP_GRACEFUL_SHUTDOWN_QUIET_PERIOD_MILLIS =
             ClientFactoryOption.define("WORKER_GROUP_GRACEFUL_SHUTDOWN_QUIET_PERIOD_MILLIS",
                                        Flags.defaultClientWorkerGroupGracefulShutdownQuietPeriodMillis());

     /**
      * The graceful worker group pool time out in milliseconds.
      */
+    @UnstableApi
     public static final ClientFactoryOption<Long> WORKER_GROUP_GRACEFUL_SHUTDOWN_TIMEOUT_MILLIS =
             ClientFactoryOption.define("WORKER_GROUP_GRACEFUL_SHUTDOWN_TIMEOUT_MILLIS",
                                        Flags.defaultClientWorkerGroupGracefulShutdownTimeoutMillis());

678-690: Add @UnstableApi annotation to the new accessor methods.

These are newly added public methods. As per coding guidelines, new public methods should have the @UnstableApi annotation.

Apply this diff:

+    @UnstableApi
     public long workerGroupGracefulShutdownQuietPeriodMillis() {
         return get(WORKER_GROUP_GRACEFUL_SHUTDOWN_QUIET_PERIOD_MILLIS);
     }

+    @UnstableApi
     public long workerGroupGracefulShutdownTimeoutMillis() {
         return get(WORKER_GROUP_GRACEFUL_SHUTDOWN_TIMEOUT_MILLIS);
     }
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0ca3e01 and e66a48f.

📒 Files selected for processing (7)
  • core/src/main/java/com/linecorp/armeria/client/ClientFactoryBuilder.java (1 hunks)
  • core/src/main/java/com/linecorp/armeria/client/ClientFactoryOptions.java (2 hunks)
  • core/src/main/java/com/linecorp/armeria/client/HttpClientFactory.java (2 hunks)
  • core/src/main/java/com/linecorp/armeria/common/DefaultFlagsProvider.java (2 hunks)
  • core/src/main/java/com/linecorp/armeria/common/Flags.java (2 hunks)
  • core/src/main/java/com/linecorp/armeria/common/FlagsProvider.java (1 hunks)
  • core/src/main/java/com/linecorp/armeria/server/Server.java (2 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.java

⚙️ CodeRabbit configuration file

**/*.java: - The primary coding conventions and style guide for this project are defined in site/src/pages/community/developer-guide.mdx. Please strictly adhere to this file as the ultimate source of truth for all style and convention-related feedback.

2. Specific check for @UnstableApi

  • Review all newly added public classes and methods to ensure they have the @UnstableApi annotation.
  • However, this annotation is NOT required under the following conditions:
    • If the class or method is located in a package containing .internal.
    • If a public method is part of a class that is already annotated with @UnstableApi.

Files:

  • core/src/main/java/com/linecorp/armeria/server/Server.java
  • core/src/main/java/com/linecorp/armeria/common/FlagsProvider.java
  • core/src/main/java/com/linecorp/armeria/client/HttpClientFactory.java
  • core/src/main/java/com/linecorp/armeria/common/DefaultFlagsProvider.java
  • core/src/main/java/com/linecorp/armeria/client/ClientFactoryBuilder.java
  • core/src/main/java/com/linecorp/armeria/client/ClientFactoryOptions.java
  • core/src/main/java/com/linecorp/armeria/common/Flags.java
🧬 Code graph analysis (2)
core/src/main/java/com/linecorp/armeria/client/ClientFactoryBuilder.java (1)
core/src/main/java/com/linecorp/armeria/client/ClientFactoryOptions.java (1)
  • ClientFactoryOptions (59-775)
core/src/main/java/com/linecorp/armeria/client/ClientFactoryOptions.java (1)
core/src/main/java/com/linecorp/armeria/common/Flags.java (1)
  • Flags (106-1939)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: CodeQL analysis (java)
  • GitHub Check: Agent
  • GitHub Check: Summary
🔇 Additional comments (5)
core/src/main/java/com/linecorp/armeria/client/HttpClientFactory.java (1)

498-507: LGTM!

The shutdown logic correctly applies the configurable quiet period and timeout values. The listener properly logs failures while ensuring the future completes regardless of the shutdown outcome.

core/src/main/java/com/linecorp/armeria/common/DefaultFlagsProvider.java (1)

326-334: Method implementations are correct.

The override methods correctly return the corresponding constants. Once the constant values are fixed (see previous comment), these will work as expected.

core/src/main/java/com/linecorp/armeria/server/Server.java (2)

693-698: LGTM!

The worker group shutdown correctly uses the server's graceful shutdown configuration with proper millisecond conversion.


719-724: LGTM!

The boss group shutdown is consistently configured with the same graceful shutdown settings as the worker group.

core/src/main/java/com/linecorp/armeria/common/FlagsProvider.java (1)

590-620: LGTM!

The new provider methods follow the established pattern with proper Javadoc. Since FlagsProvider is already annotated with @UnstableApi, no additional annotation is needed for these methods. As per coding guidelines, the class-level annotation covers these additions.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds customizable graceful shutdown settings for Netty EventLoopGroups on both client and server sides. The motivation is to speed up E2E integration tests by avoiding default graceful shutdown timeouts.

Key changes:

  • Implemented server-side graceful shutdown settings for worker and boss groups
  • Added new client-side configuration flags for worker group graceful shutdown (quiet period and timeout)
  • Provided builder methods in ClientFactoryBuilder to configure these settings

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
Server.java Applies graceful shutdown settings when stopping worker and boss groups
FlagsProvider.java Adds interface methods for new client worker group shutdown configuration
Flags.java Defines static fields and getters for the new configuration flags
DefaultFlagsProvider.java Defines default values for worker group shutdown settings
HttpClientFactory.java Applies graceful shutdown settings when closing client factory
ClientFactoryOptions.java Defines new options and getters for worker group graceful shutdown
ClientFactoryBuilder.java Adds builder methods to configure worker group graceful shutdown

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

…`EventLoopGroup`s

Fixes according to automatic review complaints.

Refs: line#5813
@novoj novoj requested a review from Copilot November 30, 2025 21:41
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
core/src/main/java/com/linecorp/armeria/common/Flags.java (1)

1087-1103: Clarify Javadoc wording for the quiet period behavior.

The Javadoc contains inconsistent descriptions of what {@code 0} means:

  • Line 1089 states: "0 disables the quiet period"
  • Line 1094 states: "0 disables the graceful shutdown"

These statements are contradictory within the same method's documentation. Setting the quiet period to 0 removes only the quiet period, not necessarily the entire graceful shutdown (the timeout can still apply). Consider updating line 1094 to match the more precise wording used elsewhere, such as in ClientFactoryBuilder line 931: "0 removes the quiet period entirely."

  * Returns the default client-side graceful worker group shutdown quiet period in milliseconds.
- * {@code 0} disables the quiet period.
+ * The quiet period allows tasks to complete before shutdown proceeds.
  *
  * <p>The default value of this flag is
  * {@value DefaultFlagsProvider#DEFAULT_CLIENT_WORKER_GROUP_GRACEFUL_SHUTDOWN_QUIET_PERIOD_MILLIS}.
  * Specify the {@code -Dcom.linecorp.armeria.defaultClientWorkerGroupGracefulShutdownQuietPeriodMillis=<long>}
- * JVM option to override the default value. {@code 0} disables the graceful shutdown.
+ * JVM option to override the default value. {@code 0} removes the quiet period entirely.
  * </p>
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e66a48f and 1fbb70f.

📒 Files selected for processing (3)
  • core/src/main/java/com/linecorp/armeria/client/ClientFactoryBuilder.java (1 hunks)
  • core/src/main/java/com/linecorp/armeria/common/DefaultFlagsProvider.java (2 hunks)
  • core/src/main/java/com/linecorp/armeria/common/Flags.java (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • core/src/main/java/com/linecorp/armeria/common/DefaultFlagsProvider.java
🧰 Additional context used
📓 Path-based instructions (1)
**/*.java

⚙️ CodeRabbit configuration file

**/*.java: - The primary coding conventions and style guide for this project are defined in site/src/pages/community/developer-guide.mdx. Please strictly adhere to this file as the ultimate source of truth for all style and convention-related feedback.

2. Specific check for @UnstableApi

  • Review all newly added public classes and methods to ensure they have the @UnstableApi annotation.
  • However, this annotation is NOT required under the following conditions:
    • If the class or method is located in a package containing .internal.
    • If a public method is part of a class that is already annotated with @UnstableApi.

Files:

  • core/src/main/java/com/linecorp/armeria/common/Flags.java
  • core/src/main/java/com/linecorp/armeria/client/ClientFactoryBuilder.java
🧬 Code graph analysis (1)
core/src/main/java/com/linecorp/armeria/client/ClientFactoryBuilder.java (1)
core/src/main/java/com/linecorp/armeria/client/ClientFactoryOptions.java (1)
  • ClientFactoryOptions (59-775)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Summary
🔇 Additional comments (2)
core/src/main/java/com/linecorp/armeria/common/Flags.java (1)

294-301: LGTM! The swapped wiring issue has been corrected.

The constants are now correctly wired to their respective provider methods and flag names. The previous issue where timeout was reading from quiet period and vice versa has been resolved.

core/src/main/java/com/linecorp/armeria/client/ClientFactoryBuilder.java (1)

929-975: LGTM! Worker group graceful shutdown configuration methods are well-implemented.

All four methods have been properly annotated with @UnstableApi as requested in previous reviews. The implementation follows established patterns:

  • Duration overloads correctly delegate to millisecond variants
  • Validation ensures non-negative values
  • Options are stored in the appropriate ClientFactoryOptions keys
  • Fluent API is maintained by returning this
  • Javadoc clearly describes the behavior of each parameter

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1fbb70f and 81e5b87.

📒 Files selected for processing (1)
  • core/src/main/java/com/linecorp/armeria/client/ClientFactoryOptions.java (2 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.java

⚙️ CodeRabbit configuration file

**/*.java: - The primary coding conventions and style guide for this project are defined in site/src/pages/community/developer-guide.mdx. Please strictly adhere to this file as the ultimate source of truth for all style and convention-related feedback.

2. Specific check for @UnstableApi

  • Review all newly added public classes and methods to ensure they have the @UnstableApi annotation.
  • However, this annotation is NOT required under the following conditions:
    • If the class or method is located in a package containing .internal.
    • If a public method is part of a class that is already annotated with @UnstableApi.

Files:

  • core/src/main/java/com/linecorp/armeria/client/ClientFactoryOptions.java
🧬 Code graph analysis (1)
core/src/main/java/com/linecorp/armeria/client/ClientFactoryOptions.java (1)
core/src/main/java/com/linecorp/armeria/common/Flags.java (1)
  • Flags (106-1941)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Summary

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 8 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

…`EventLoopGroup`s

Fixes according to automatic review complaints.

Refs: line#5813
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 4 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Contributor

@jrhee17 jrhee17 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR.

For 1) consistency across APIs regarding graceful shutdown behavior 2) less methods/flags for setting graceful shutdown fields I'm wondering if the following API makes sense:

  1. Generalize GracefulShutdown so that it can be for methods other than server graceful shutdown
    As a first step, remove GracefulShutdown#toException. Allow users to specify the toException behavior on the server directly
+++ b/core/src/main/java/com/linecorp/armeria/server/GracefulShutdown.java
public interface GracefulShutdown {
...
-
-    /**
-     * Returns an {@link Throwable} to terminate a pending request when the server is shutting down.
-     * The exception will be converted to an {@link HttpResponse} by {@link ServerErrorHandler}.
-     *
-     * <p>If null is returned, the request will be terminated with {@link ShuttingDownException} that will be
-     * converted to an {@link HttpStatus#SERVICE_UNAVAILABLE} response.
-     */
-    Throwable toException(ServiceRequestContext ctx, HttpRequest request);
@@ -949,6 +951,14 @@ public final class ServerBuilder implements TlsSetters, ServiceConfigsBuilder<Se
+    @UnstableApi
+    public ServerBuilder gracefulShutdown(
+            GracefulShutdown gracefulShutdown,
+            BiFunction<? super ServiceRequestContext, ? super HttpRequest, ? extends Throwable> toException) {
+        this.gracefulShutdown = requireNonNull(gracefulShutdown, "gracefulShutdown");
+        return this;
+    }
+
  1. Move GracefulShutdown, GracefulShutdownBuilder, DefaultGracefulShutdown to the common package (com.linecorp.armeria.common.GracefulShutdown)

  2. Allow users to specify GracefulShutdown for worker groups separately for each server/clientFactory.

e.g.

ClientFactory.builder().workerGroup(workerGroup, GracefulShutdown)
Server.builder().workerGroup(workerGroup, GracefulShutdown)
Flags.workerGroupGracefulShutdown()

This will incur some breaking changes, so pinging other @line/dx members in case there is a different opinion

@ikhoon
Copy link
Contributor

ikhoon commented Dec 1, 2025

Generalizing GracefulShutdown sounds a good idea. In addition, it would also be great if toException() could be applied to the client's pending requests.

Currently, when a ClientFactory is closed, all channels are closed accordingly, which causes the pending requests to end with ClosedSessionException. I think it would be clearer to use a ShuttingDownException instead, so that users can see that the in-flight requests were terminated explicitly by closing the ClientFactory, rather than a transport error. toException could be used an extension point to customize the default behavior.

@trustin
Copy link
Member

trustin commented Dec 2, 2025

I like the approach here and the feedback from @jrhee17 and @ikhoon. Thanks for bringing back to the table, @novoj! 🙇

@novoj
Copy link
Author

novoj commented Dec 2, 2025

I'd be grateful if @jrhee17 or @ikhoon help me to carve out an idea where to start with the changes and where to look. I'm newbie to Armeria codebase. Pinpointing key classes / methods which would be impacted by the change would help a lot.

@jrhee17
Copy link
Contributor

jrhee17 commented Dec 3, 2025

I think it's best to start with the direct issue you would like to solve - specifying GracefulShutdown for ClientFactory#workerGroup.

What do you think of starting with adding the following APIs in ClientFactoryBuilder.java, ClientFactoryOption.java?

    public ClientFactoryBuilder workerGroup(EventLoopGroup workerGroup, boolean shutdownOnClose,
                                                                          GracefulShutdown gracefulShutdown) {
    }

    public ClientFactoryBuilder workerGroup(int numThreads, GracefulShutdown gracefulShutdown) {
    }
    public static final ClientFactoryOption<GracefulShutdown> WORKER_GROUP_GRACEFUL_SHUTDOWN =
            ClientFactoryOption.define("WORKER_GROUP_GRACEFUL_SHUTDOWN", Flags.workerGroupGracefulShutdown());

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
core/src/main/java/com/linecorp/armeria/common/Flags.java (1)

1083-1118: Clarify Javadoc for the graceful shutdown settings.

The @UnstableApi annotations are correctly present. However, the Javadoc has some wording that could be clearer:

  1. Line 1090 states "0 disables the graceful shutdown" but this is misleading—setting the quiet period to 0 only removes the quiet period, not the entire graceful shutdown (the timeout still applies). Consider removing this sentence as line 1085 already clearly states "0 disables the quiet period".

  2. Line 1108 states "0 disables the graceful shutdown" which is redundant with line 1103 that already says "0 disables the timeout and closes the worker group immediately". Consider removing line 1108 to avoid duplication.

🔎 Proposed Javadoc refinements
     /**
      * Returns the default client-side graceful worker group shutdown quiet period in milliseconds.
      * {@code 0} disables the quiet period.
      *
      * <p>The default value of this flag is
      * {@value DefaultFlagsProvider#DEFAULT_CLIENT_WORKER_GROUP_GRACEFUL_SHUTDOWN_QUIET_PERIOD_MILLIS}.
      * Specify the {@code -Dcom.linecorp.armeria.defaultClientWorkerGroupGracefulShutdownQuietPeriodMillis=<long>}
-     * JVM option to override the default value. {@code 0} disables the graceful shutdown.
+     * JVM option to override the default value.
      * </p>
      *
      * @see ClientFactoryBuilder#workerGroupGracefulShutdownQuietPeriod(Duration)
      * @see ClientFactoryBuilder#workerGroupGracefulShutdownQuietPeriodMillis(long)
      */
     @UnstableApi
     public static long defaultClientWorkerGroupGracefulShutdownQuietPeriodMillis() {
         return DEFAULT_CLIENT_WORKER_GROUP_GRACEFUL_SHUTDOWN_QUIET_PERIOD_MILLIS;
     }

     /**
      * Returns the default client-side graceful worker group shutdown timeout in milliseconds.
      * {@code 0} disables the timeout and closes the worker group immediately.
      *
      * <p>The default value of this flag is
      * {@value DefaultFlagsProvider#DEFAULT_CLIENT_WORKER_GROUP_GRACEFUL_SHUTDOWN_TIMEOUT_MILLIS}.
      * Specify the {@code -Dcom.linecorp.armeria.defaultClientWorkerGroupGracefulShutdownTimeoutMillis=<long>}
-     * JVM option to override the default value. {@code 0} disables the graceful shutdown.
+     * JVM option to override the default value.
      * </p>
      *
      * @see ClientFactoryBuilder#workerGroupGracefulShutdownTimeout(Duration)
      * @see ClientFactoryBuilder#workerGroupGracefulShutdownTimeoutMillis(long)
      */
     @UnstableApi
     public static long defaultClientWorkerGroupGracefulShutdownTimeoutMillis() {
         return DEFAULT_CLIENT_WORKER_GROUP_GRACEFUL_SHUTDOWN_TIMEOUT_MILLIS;
     }

Based on past review comments, this refinement aligns with feedback from Copilot about removing redundant/contradictory statements.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 81e5b87 and 56c72ee.

📒 Files selected for processing (4)
  • core/src/main/java/com/linecorp/armeria/client/ClientFactoryBuilder.java
  • core/src/main/java/com/linecorp/armeria/client/ClientFactoryOptions.java
  • core/src/main/java/com/linecorp/armeria/client/HttpClientFactory.java
  • core/src/main/java/com/linecorp/armeria/common/Flags.java
🚧 Files skipped from review as they are similar to previous changes (1)
  • core/src/main/java/com/linecorp/armeria/client/ClientFactoryOptions.java
🧰 Additional context used
📓 Path-based instructions (1)
**/*.java

⚙️ CodeRabbit configuration file

**/*.java: - The primary coding conventions and style guide for this project are defined in site/src/pages/community/developer-guide.mdx. Please strictly adhere to this file as the ultimate source of truth for all style and convention-related feedback.

2. Specific check for @UnstableApi

  • Review all newly added public classes and methods to ensure they have the @UnstableApi annotation.
  • However, this annotation is NOT required under the following conditions:
    • If the class or method is located in a package containing .internal or .testing.
    • If the class or method is located in a test source set.
    • If a public method is part of a class that is already annotated with @UnstableApi.

Files:

  • core/src/main/java/com/linecorp/armeria/client/HttpClientFactory.java
  • core/src/main/java/com/linecorp/armeria/client/ClientFactoryBuilder.java
  • core/src/main/java/com/linecorp/armeria/common/Flags.java
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Summary
🔇 Additional comments (4)
core/src/main/java/com/linecorp/armeria/common/Flags.java (1)

294-301: LGTM! Constants are correctly wired.

The initialization of the two graceful shutdown constants is now correct, with each reading from the appropriate provider method and flag name. The fix in commit 1fbb70f successfully resolved the swapped wiring issue.

core/src/main/java/com/linecorp/armeria/client/HttpClientFactory.java (2)

30-30: LGTM! Import is necessary.

The TimeUnit import is required for the graceful shutdown configuration on line 469.


466-475: LGTM! Graceful shutdown now uses configurable timing.

The worker group shutdown sequence correctly applies the new configurable quiet period and timeout values from ClientFactoryOptions. The parameters are passed in the correct order to shutdownGracefully(), and the future is properly completed via the listener regardless of success or failure.

core/src/main/java/com/linecorp/armeria/client/ClientFactoryBuilder.java (1)

935-982: LGTM! New builder methods are correctly implemented.

All four graceful shutdown configuration methods are properly implemented:

  • @UnstableApi annotations are present on all methods as required by coding guidelines
  • Duration overloads correctly delegate to millisecond overloads
  • Validation ensures non-negative values
  • Correct ClientFactoryOptions keys are used
  • Javadoc clearly describes the behavior, including the effect of 0
  • Methods follow the existing builder patterns and return this for fluent chaining

This successfully addresses the past review comments requesting the @UnstableApi annotations.

@novoj
Copy link
Author

novoj commented Dec 24, 2025

Here is what I did:

  1. I removed the logic inside the Server class because that's where most of the reservations and suggestions for changes were.
  2. I updated (synced) my branch with the current main branch.
  3. I polished some JavaDoc.

The client-side implementation remained the same. I think the actual handling is much more aligned with existing methods, such as:

  • com.linecorp.armeria.common.FlagsProvider#defaultClientWorkerGroupGracefulShutdownTimeoutMillis
  • com.linecorp.armeria.common.FlagsProvider#defaultClientHttp2GracefulShutdownTimeoutMillis

The newly proposed methods by @jrhee17 in the comment at #6528 (comment) suit the server-side API better, in my opinion. The current pull request is minimalistic and still solves my problem. It seems that the delays in my tests are caused by the client rather than the server shutdown.

This patch is consistent and can be merged separately from the server-side solution, which I may attempt in a separate pull request.

@jrhee17
Copy link
Contributor

jrhee17 commented Dec 26, 2025

This patch is consistent and can be merged separately from the server-side solution, which I may attempt in a separate pull request.

Thanks for the update.

My thought is that we will end up using the GracefulShutdown interface extensively within the code-base as graceful shutdown is a well established term/concept amongst current users. I think it may be best to lean into GracefulShutdown as the canonical concept/interface sooner rather than later, even if the current patch can technically avoid relying on it.

What I had in mind was just accepting GracefulShutdown as-is for now, and treating this PR as the first step that establishes the client-side event loop shutdown behavior in a way that’s consistent with what we’ll want long-term across the codebase.

ref: https://github.com/jrhee17/armeria/tree/poc/client-eventloop-graceful

Concretely, I’d suggest:

Merge this PR on its own merits, but align the public-facing surface area with GracefulShutdown (naming + intent), rather than introducing a parallel concept we’ll later need to reconcile.

Then follow up with a second PR that:

Once this PR was merged, I was thinking of adding another PR which:

  1. cleans up/generalizes the GracefulShutdown implementation by deprecating the toException method (and accept the toException function separately if necessary)
  2. moves GracefulShutdown to the common package since this is a cross-cutting abstraction we’re likely to reuse broadly.

Either I can work on the final clean up, or you can continue with the work if interested.

This way we keep the nice property of this changeset being mergeable independently, while also converging on the terminology and abstraction that users (and our own code) are moving towards.

Let me know what you think

@novoj
Copy link
Author

novoj commented Dec 27, 2025

I tried to materialize your proposal @jrhee17 in separate pull request #6563 - it's much larger and I'm not sure I made everything right - or better said: according your expectations.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Provide a way to customize the graceful shutdown delay of Netty EventLoopGroups

4 participants