Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 83 additions & 0 deletions A117-ring-hash-exit-idle.md
Original file line number Diff line number Diff line change
@@ -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
Comment thread
easwars marked this conversation as resolved.
Outdated
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.
Comment thread
easwars marked this conversation as resolved.
Outdated

### 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
Comment thread
ejona86 marked this conversation as resolved.
Outdated
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
Comment thread
ejona86 marked this conversation as resolved.
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
3 changes: 2 additions & 1 deletion A42-xds-ring-hash-lb-policy.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
11 changes: 8 additions & 3 deletions A61-IPv4-IPv6-dualstack-backends.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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]
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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