SIGN IN SIGN UP

endpointsharding: decouple locking, and simplify ChildState API (#9290)

This change refactors `balancer/endpointsharding` by having a two-level
locking strategy: one for the state in the `endpointSharding` balancer
and one for the state that is maintained for every endpoint. It
continues to guarantee the mutual exclusion requirements of the
`balancer.Balancer` API methods while keeping the code simple and
deadlock-free.

Summary of Changes:
- Decoupled & Safe Locking Model:
- Per-Child Isolation (`childMu`): Guarantees strict mutual exclusion
for all `balancer.Balancer` API calls to a specific child balancer. This
protects against races when `ExitIdle` is triggered asynchronously by
the picker or auto-reconnection.
- Parent Aggregation (`mu`): Protects the global endpoints map and
aggregated state.
- Deadlock Prevention: Establishes a strict lock hierarchy where parent
locks are never held when calling into a child.
- Simplify the `ChildState` API:
- Replaced the single-method `ExitIdler` interface with with a
first-class function `ExitIdle func()`.
  - Removed `ExitIdler` from package `endpointsharding`.
- Updated `balancer/ringhash` to consume the function callback directly.

RELEASE NOTES: none
E
Easwar Swaminathan committed
538bb2f7af6e36be46ec1d2ae90f65b972f14083
Parent: bf9e7cd
Committed by GitHub <noreply@github.com> on 8/14/2026, 8:33:32 PM