From 05b91aa2533d6128801916e3e389bd9736113efe Mon Sep 17 00:00:00 2001 From: Doug Fawley Date: Fri, 15 May 2026 10:19:36 -0700 Subject: [PATCH 1/3] A117: Ring Hash exit_idle behavior changes --- A117-ring-hash-exit-idle.md | 83 +++++++++++++++++++++++++++++ A42-xds-ring-hash-lb-policy.md | 3 +- A61-IPv4-IPv6-dualstack-backends.md | 11 ++-- 3 files changed, 93 insertions(+), 4 deletions(-) create mode 100644 A117-ring-hash-exit-idle.md diff --git a/A117-ring-hash-exit-idle.md b/A117-ring-hash-exit-idle.md new file mode 100644 index 000000000..4d24285b4 --- /dev/null +++ b/A117-ring-hash-exit-idle.md @@ -0,0 +1,83 @@ +A117: Ring Hash Exit Idle Behavior Changes +---- +* Author(s): dfawley@ +* Approver(s): markdroth@, ejona@ +* Implemented in: +* Last updated: 2026-05-15 +* Discussion at: https://groups.google.com/g/grpc-io/c/ByCPdvi5lrQ + +## Abstract + +Update the Ring Hash LB policy to create connections when expliictly requested +by the channel to do so, instead of ignoring the request. + +## Background + +The Ring Hash LB policy, as defined in [gRFC A42][A42], does not create +connections upon creation. Even though it is not specified, all implementations +of gRPC also ignored calls to the "exit idle" / "request connection" method. + +It has been observed that this behavior can cause problems, however. +Specifically, when using the gRPC [connectivity API][], if an application +requests a channel using ring-hash to connect, but ring hash ignores the +incoming request from the channel, the application will never see a change to +the state of the channel. If the connectivity state is used for something like +computing the health of a server, that can cause serious problems, as an +unhealthy server will not receive the traffic it needs to begin connecting. + +### Related Proposals: + +* [gRFC A42: xDS Ring Hash LB Policy][A42] +* [gRFC A76: Improvements to the Ring Hash LB Policy][A76] +* [gRFC A61: IPv4 and IPv6 Dualstack Backend Support][A61rh] + +## Proposal + +This proposal makes two behavior changes: + +1. Ring Hash should enter the CONNECTING state when the channel requests it to + exit idle mode, instead of ignoring the request. + + This will cause the eager-connection logic described in [gRFC A61][A61rh] to + trigger: + + > when the aggregated connectivity state is either TRANSIENT_FAILURE or + > CONNECTING, the ring_hash policy proactively triggers connection attempts + > across all of the subchannels, even without seeing any picks. + +2. New connection attempts not triggered by an RPC should begin from a + randomized location (behavior change from [gRFC A61][A61rh]'s + TRANSIENT_FAILURE / CONNECTING behavior), which currently states the choice + of endpoints is up to the implementation: + + > It does not matter which IDLE endpoint is chosen; that is left up to the + > implementation to determine. + + Using a randomized endpoint will ensure that load is distributed evenly + across available backends if many individual clients are instructed to + connect at the same time. + +### Temporary environment variable protection + +Even though this is a behavior change, as the behavior is triggered by the +application, this feature does not need to be protected by a standardized +environment variable. Individual langauge implementations may wish to provide +their language-specific mechanism to revert the behavior change temporarily in +the event that issues are encountered by users. + +## Rationale + +Another option is to change nothing in the Ring Hash policy and require users to +consider "IDLE" as a "healthy" state in their application. This is still +surprising / unintuitive behavior, and it would be too hard to communicate this +to all users. + +## Implementation + +The implementation should be done in all languages that support Ring Hash. + + +[A42]: A42-xds-ring-hash-lb-policy.md +[A76]: A76-ring-hash-improvements.md +[A61rh]: A61-IPv4-IPv6-dualstack-backends.md#ring-hash +[connectivity API]: https://github.com/grpc/grpc/blob/master/doc/connectivity-semantics-and-api.md \ No newline at end of file diff --git a/A42-xds-ring-hash-lb-policy.md b/A42-xds-ring-hash-lb-policy.md index 90726cf22..df24c1a45 100644 --- a/A42-xds-ring-hash-lb-policy.md +++ b/A42-xds-ring-hash-lb-policy.md @@ -6,7 +6,8 @@ A42: xDS Ring Hash LB Policy * Implemented in: Java (C-core and Go in progress) * Last updated: 2021-06-04 * Discussion at: https://groups.google.com/g/grpc-io/c/_Z_oiWVXf6k -* Updated by: [A61: IPv4 and IPv6 Dualstack Backend Support](A61-IPv4-IPv6-dualstack-backends.md) +* Updated by: [A61: IPv4 and IPv6 Dualstack Backend Support](A61-IPv4-IPv6-dualstack-backends.md), [A76: Improvements to the Ring Hash LB Policy](A76-ring-hash-improvements.md), and [A117: Ring Hash Exit Idle Behavior Changes](A117-ring-hash-exit-idle.md) + ## Abstract diff --git a/A61-IPv4-IPv6-dualstack-backends.md b/A61-IPv4-IPv6-dualstack-backends.md index 6eb690b41..8243f0145 100644 --- a/A61-IPv4-IPv6-dualstack-backends.md +++ b/A61-IPv4-IPv6-dualstack-backends.md @@ -6,6 +6,7 @@ A61: IPv4 and IPv6 Dualstack Backend Support * Implemented in: C-core * Last updated: 2025-03-06 * Discussion at: https://groups.google.com/g/grpc-io/c/VjORlKP97cE/m/ihqyN32TAQAJ +* Updated by: [A76: Improvements to the Ring Hash LB Policy](A76-ring-hash-improvements.md) and [A117: Ring Hash Exit Idle Behavior Changes][A117] ## Abstract @@ -43,7 +44,7 @@ addresses per endpoint in xDS. We will support the new xDS APIs being added for that effort as well. Note that this change has implications for session affinity behavior in xDS. -### Related Proposals: +### Related Proposals: * [Support for dual stack EDS endpoints in Envoy][envoy-design] * [gRFC A17: Client-Side Health Checking][A17] * [gRFC A27: xDS-Based Global Load Balancing][A27] @@ -596,10 +597,13 @@ if the aggregated connectivity state is TRANSIENT_FAILURE or CONNECTING and there are no endpoints in CONNECTING state, the ring_hash policy will choose one of the endpoints in IDLE state (if any) to trigger a connection attempt on. It does not matter which IDLE endpoint is chosen; that is -left up to the implementation to determine. One possible implementation -of this is shown in the following pseudo-code: +left up to the implementation to determine. (Update: gRFC [A117][] now +specifies a _random_ endpoint should be chosen.) One possible implementation of +this is shown in the following pseudo-code: ``` +# Updated to show a randomized starting location per gRFC A117. +endpoints = shuffle(endpoints); if (aggregated_state_is_connecting_or_transient_failure) { first_idle_index = -1; for (i = 0; i < endpoints.size(); ++i) { @@ -961,3 +965,4 @@ N/A [RFC-8305]: https://www.rfc-editor.org/rfc/rfc8305 [A62]: A62-pick-first.md [backoff-spec]: https://github.com/grpc/grpc/blob/master/doc/connection-backoff.md +[A117]: A117-ring-hash-exit-idle.md From 0bcab330fdac324abca210f4fa6f20073892ef87 Mon Sep 17 00:00:00 2001 From: Doug Fawley Date: Tue, 19 May 2026 08:22:49 -0700 Subject: [PATCH 2/3] ejona comments --- A117-ring-hash-exit-idle.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/A117-ring-hash-exit-idle.md b/A117-ring-hash-exit-idle.md index 4d24285b4..b610ef358 100644 --- a/A117-ring-hash-exit-idle.md +++ b/A117-ring-hash-exit-idle.md @@ -35,8 +35,9 @@ unhealthy server will not receive the traffic it needs to begin connecting. This proposal makes two behavior changes: -1. Ring Hash should enter the CONNECTING state when the channel requests it to - exit idle mode, instead of ignoring the request. +1. Ring Hash should enter the CONNECTING state if it is currently in the IDLE + state and the channel requests it to exit idle mode, instead of ignoring the + request. This will cause the eager-connection logic described in [gRFC A61][A61rh] to trigger: @@ -45,10 +46,10 @@ This proposal makes two behavior changes: > CONNECTING, the ring_hash policy proactively triggers connection attempts > across all of the subchannels, even without seeing any picks. -2. New connection attempts not triggered by an RPC should begin from a - randomized location (behavior change from [gRFC A61][A61rh]'s - TRANSIENT_FAILURE / CONNECTING behavior), which currently states the choice - of endpoints is up to the implementation: +2. New connection attempts not triggered by an RPC should begin with a random + endpoint, ignoring endpoint weights. This is a behavior change from [gRFC + A61][A61rh]'s TRANSIENT_FAILURE / CONNECTING behavior, which currently states + the choice of endpoints is up to the implementation: > It does not matter which IDLE endpoint is chosen; that is left up to the > implementation to determine. From 17b21ce5b5544b81c41d1f50bc2ab154dd13094b Mon Sep 17 00:00:00 2001 From: Doug Fawley Date: Mon, 13 Jul 2026 15:06:30 -0700 Subject: [PATCH 3/3] easwars comments --- A117-ring-hash-exit-idle.md | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/A117-ring-hash-exit-idle.md b/A117-ring-hash-exit-idle.md index b610ef358..054f4acde 100644 --- a/A117-ring-hash-exit-idle.md +++ b/A117-ring-hash-exit-idle.md @@ -8,8 +8,8 @@ A117: Ring Hash Exit Idle Behavior Changes ## Abstract -Update the Ring Hash LB policy to create connections when expliictly requested -by the channel to do so, instead of ignoring the request. +Update the Ring Hash LB policy to create connections when explictly requested by +the channel to do so, instead of ignoring the request. ## Background @@ -19,11 +19,12 @@ of gRPC also ignored calls to the "exit idle" / "request connection" method. It has been observed that this behavior can cause problems, however. Specifically, when using the gRPC [connectivity API][], if an application -requests a channel using ring-hash to connect, but ring hash ignores the +requests a channel using ring hash to connect, but ring hash ignores the incoming request from the channel, the application will never see a change to -the state of the channel. If the connectivity state is used for something like -computing the health of a server, that can cause serious problems, as an -unhealthy server will not receive the traffic it needs to begin connecting. +the state of the channel. Further, if this channel's connectivity state is used +to compute the health of a server using that channel, that can cause serious +problems, as an unhealthy server will not receive the traffic it needs to make +ring hash connect. ### Related Proposals: @@ -81,4 +82,4 @@ The implementation should be done in all languages that support Ring Hash. [A42]: A42-xds-ring-hash-lb-policy.md [A76]: A76-ring-hash-improvements.md [A61rh]: A61-IPv4-IPv6-dualstack-backends.md#ring-hash -[connectivity API]: https://github.com/grpc/grpc/blob/master/doc/connectivity-semantics-and-api.md \ No newline at end of file +[connectivity API]: https://github.com/grpc/grpc/blob/master/doc/connectivity-semantics-and-api.md