Skip to content

Commit b036491

Browse files
committed
A117: Ring Hash exit_idle behavior changes
1 parent ba72cc0 commit b036491

3 files changed

Lines changed: 93 additions & 4 deletions

File tree

A117-ring-hash-exit-idle.md

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
A117: Ring Hash Exit Idle Behavior Changes
2+
----
3+
* Author(s): dfawley@
4+
* Approver(s): markdroth@, ejona@
5+
* Implemented in:
6+
* Last updated: 2026-05-15
7+
* Discussion at: https://groups.google.com/g/grpc-io/c/ByCPdvi5lrQ
8+
9+
## Abstract
10+
11+
Update the Ring Hash LB policy to create connections when expliictly requested
12+
by the channel to do so, instead of ignoring the request.
13+
14+
## Background
15+
16+
The Ring Hash LB policy, as defined in [gRFC A42][A42], does not create
17+
connections upon creation. Even though it is not specified, all implementations
18+
of gRPC also ignored calls to the "exit idle" / "request connection" method.
19+
20+
It has been observed that this behavior can cause problems, however.
21+
Specifically, when using the gRPC [connectivity API][], if an application
22+
requests a channel using ring-hash to connect, but ring hash ignores the
23+
incoming request from the channel, the application will never see a change to
24+
the state of the channel. If the connectivity state is used for something like
25+
computing the health of a server, that can cause serious problems, as an
26+
unhealthy server will not receive the traffic it needs to begin connecting.
27+
28+
### Related Proposals:
29+
30+
* [gRFC A42: xDS Ring Hash LB Policy][A42]
31+
* [gRFC A76: Improvements to the Ring Hash LB Policy][A76]
32+
* [gRFC A61: IPv4 and IPv6 Dualstack Backend Support][A61rh]
33+
34+
## Proposal
35+
36+
This proposal makes two behavior changes:
37+
38+
1. Ring Hash should enter the CONNECTING state when the channel requests it to
39+
exit idle mode, instead of ignoring the request.
40+
41+
This will cause the eager-connection logic described in [gRFC A61][A61rh] to
42+
trigger:
43+
44+
> when the aggregated connectivity state is either TRANSIENT_FAILURE or
45+
> CONNECTING, the ring_hash policy proactively triggers connection attempts
46+
> across all of the subchannels, even without seeing any picks.
47+
48+
2. New connection attempts not triggered by an RPC should begin from a
49+
randomized location (behavior change from [gRFC A61][A61rh]'s
50+
TRANSIENT_FAILURE / CONNECTING behavior), which currently states the choice
51+
of endpoints is up to the implementation:
52+
53+
> It does not matter which IDLE endpoint is chosen; that is left up to the
54+
> implementation to determine.
55+
56+
Using a randomized endpoint will ensure that load is distributed evenly
57+
across available backends if many individual clients are instructed to
58+
connect at the same time.
59+
60+
### Temporary environment variable protection
61+
62+
Even though this is a behavior change, as the behavior is triggered by the
63+
application, this feature does not need to be protected by a standardized
64+
environment variable. Individual langauge implementations may wish to provide
65+
their language-specific mechanism to revert the behavior change temporarily in
66+
the event that issues are encountered by users.
67+
68+
## Rationale
69+
70+
Another option is to change nothing in the Ring Hash policy and require users to
71+
consider "IDLE" as a "healthy" state in their application. This is still
72+
surprising / unintuitive behavior, and it would be too hard to communicate this
73+
to all users.
74+
75+
## Implementation
76+
77+
The implementation should be done in all languages that support Ring Hash.
78+
79+
80+
[A42]: A42-xds-ring-hash-lb-policy.md
81+
[A76]: A76-ring-hash-improvements.md
82+
[A61rh]: A61-IPv4-IPv6-dualstack-backends.md#ring-hash
83+
[connectivity API]: https://github.com/grpc/grpc/blob/master/doc/connectivity-semantics-and-api.md

A42-xds-ring-hash-lb-policy.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ A42: xDS Ring Hash LB Policy
66
* Implemented in: Java (C-core and Go in progress)
77
* Last updated: 2021-06-04
88
* Discussion at: https://groups.google.com/g/grpc-io/c/_Z_oiWVXf6k
9-
* Updated by: [A61: IPv4 and IPv6 Dualstack Backend Support](A61-IPv4-IPv6-dualstack-backends.md)
9+
* 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)
10+
1011

1112
## Abstract
1213

A61-IPv4-IPv6-dualstack-backends.md

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ A61: IPv4 and IPv6 Dualstack Backend Support
66
* Implemented in: C-core
77
* Last updated: 2025-03-06
88
* Discussion at: https://groups.google.com/g/grpc-io/c/VjORlKP97cE/m/ihqyN32TAQAJ
9+
* Updated by: [A76: Improvements to the Ring Hash LB Policy]() and [A117: Ring Hash Exit Idle Behavior Changes][A117]
910

1011
## Abstract
1112

@@ -43,7 +44,7 @@ addresses per endpoint in xDS. We will support the new xDS APIs being
4344
added for that effort as well. Note that this change has implications
4445
for session affinity behavior in xDS.
4546

46-
### Related Proposals:
47+
### Related Proposals:
4748
* [Support for dual stack EDS endpoints in Envoy][envoy-design]
4849
* [gRFC A17: Client-Side Health Checking][A17]
4950
* [gRFC A27: xDS-Based Global Load Balancing][A27]
@@ -596,10 +597,13 @@ if the aggregated connectivity state is TRANSIENT_FAILURE or CONNECTING
596597
and there are no endpoints in CONNECTING state, the ring_hash policy will
597598
choose one of the endpoints in IDLE state (if any) to trigger a connection
598599
attempt on. It does not matter which IDLE endpoint is chosen; that is
599-
left up to the implementation to determine. One possible implementation
600-
of this is shown in the following pseudo-code:
600+
left up to the implementation to determine. (Update: gRFC [A117][] now
601+
specifies a _random_ endpoint should be chosen.) One possible implementation of
602+
this is shown in the following pseudo-code:
601603

602604
```
605+
# Updated to show a randomized starting location per gRFC A117.
606+
endpoints = shuffle(endpoints);
603607
if (aggregated_state_is_connecting_or_transient_failure) {
604608
first_idle_index = -1;
605609
for (i = 0; i < endpoints.size(); ++i) {
@@ -961,3 +965,4 @@ N/A
961965
[RFC-8305]: https://www.rfc-editor.org/rfc/rfc8305
962966
[A62]: A62-pick-first.md
963967
[backoff-spec]: https://github.com/grpc/grpc/blob/master/doc/connection-backoff.md
968+
[A117]: A117-ring-hash-exit-idle.md

0 commit comments

Comments
 (0)