Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

outlierdetection: fix unconditional calls of child UpdateSubConnState #6500

Merged
merged 1 commit into from
Aug 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
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
19 changes: 11 additions & 8 deletions xds/internal/balancer/outlierdetection/balancer.go
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,6 @@ func (bb) Name() string {
type scUpdate struct {
scw *subConnWrapper
state balancer.SubConnState
cb func(balancer.SubConnState)
}

type ejectionUpdate struct {
Expand Down Expand Up @@ -346,7 +345,7 @@ func (b *outlierDetectionBalancer) ResolverError(err error) {
b.child.ResolverError(err)
}

func (b *outlierDetectionBalancer) updateSubConnState(sc balancer.SubConn, state balancer.SubConnState, cb func(balancer.SubConnState)) {
func (b *outlierDetectionBalancer) updateSubConnState(sc balancer.SubConn, state balancer.SubConnState) {
b.mu.Lock()
defer b.mu.Unlock()
scw, ok := b.scWrappers[sc]
Expand All @@ -362,12 +361,11 @@ func (b *outlierDetectionBalancer) updateSubConnState(sc balancer.SubConn, state
b.scUpdateCh.Put(&scUpdate{
scw: scw,
state: state,
cb: cb,
})
}

func (b *outlierDetectionBalancer) UpdateSubConnState(sc balancer.SubConn, state balancer.SubConnState) {
b.updateSubConnState(sc, state, nil)
b.logger.Errorf("UpdateSubConnState(%v, %+v) called unexpectedly", sc, state)
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't get how if this logs an error and doesn't do anything do we keep it backward compatible?

Copy link
Contributor

Choose a reason for hiding this comment

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

Why not just keep the old flow the same (UpdateSubConnState works normally), until we delete? What's the advantage of this?

Copy link
Contributor

Choose a reason for hiding this comment

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

Oh, I guess this won't ever get called since the Channel now calls the listener callback.

Copy link
Member Author

Choose a reason for hiding this comment

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

Why not just keep the old flow the same (UpdateSubConnState works normally), until we delete? What's the advantage of this?

The goal is to catch all the places where we use the old API and update them to the new one so the old one can be deleted. If we keep the old API code working then we might miss a place where we needed to convert it when we go to delete the API itself.

}

func (b *outlierDetectionBalancer) Close() {
Expand Down Expand Up @@ -474,7 +472,7 @@ func (b *outlierDetectionBalancer) UpdateState(s balancer.State) {
func (b *outlierDetectionBalancer) NewSubConn(addrs []resolver.Address, opts balancer.NewSubConnOptions) (balancer.SubConn, error) {
var sc balancer.SubConn
oldListener := opts.StateListener
opts.StateListener = func(state balancer.SubConnState) { b.updateSubConnState(sc, state, oldListener) }
opts.StateListener = func(state balancer.SubConnState) { b.updateSubConnState(sc, state) }
sc, err := b.cc.NewSubConn(addrs, opts)
if err != nil {
return nil, err
Expand All @@ -483,6 +481,7 @@ func (b *outlierDetectionBalancer) NewSubConn(addrs []resolver.Address, opts bal
SubConn: sc,
addresses: addrs,
scUpdateCh: b.scUpdateCh,
listener: oldListener,
}
b.mu.Lock()
defer b.mu.Unlock()
Expand Down Expand Up @@ -624,8 +623,8 @@ func (b *outlierDetectionBalancer) handleSubConnUpdate(u *scUpdate) {
scw.latestState = u.state
if !scw.ejected {
b.childMu.Lock()
if u.cb != nil {
u.cb(u.state)
if scw.listener != nil {
scw.listener(u.state)
} else {
b.child.UpdateSubConnState(scw, u.state)
}
Expand All @@ -647,7 +646,11 @@ func (b *outlierDetectionBalancer) handleEjectedUpdate(u *ejectionUpdate) {
}
}
b.childMu.Lock()
b.child.UpdateSubConnState(scw, stateToUpdate)
if scw.listener != nil {
scw.listener(stateToUpdate)
} else {
b.child.UpdateSubConnState(scw, stateToUpdate)
}
b.childMu.Unlock()
}

Expand Down
6 changes: 3 additions & 3 deletions xds/internal/balancer/outlierdetection/balancer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1085,7 +1085,7 @@ func (s) TestEjectUnejectSuccessRate(t *testing.T) {

// Since no addresses are ejected, a SubConn update should forward down
// to the child.
od.UpdateSubConnState(scw1.(*subConnWrapper).SubConn, balancer.SubConnState{
od.updateSubConnState(scw1.(*subConnWrapper).SubConn, balancer.SubConnState{
ConnectivityState: connectivity.Connecting,
})

Expand Down Expand Up @@ -1147,7 +1147,7 @@ func (s) TestEjectUnejectSuccessRate(t *testing.T) {
// that address should not be forwarded downward. These SubConn updates
// will be cached to update the child sometime in the future when the
// address gets unejected.
od.UpdateSubConnState(pi.SubConn, balancer.SubConnState{
od.updateSubConnState(pi.SubConn, balancer.SubConnState{
ConnectivityState: connectivity.Connecting,
})
sCtx, cancel = context.WithTimeout(context.Background(), defaultTestShortTimeout)
Expand Down Expand Up @@ -1564,7 +1564,7 @@ func (s) TestConcurrentOperations(t *testing.T) {

// Call balancer.Balancers synchronously in this goroutine, upholding the
// balancer.Balancer API guarantee.
od.UpdateSubConnState(scw1.(*subConnWrapper).SubConn, balancer.SubConnState{
od.updateSubConnState(scw1.(*subConnWrapper).SubConn, balancer.SubConnState{
ConnectivityState: connectivity.Connecting,
})
od.ResolverError(errors.New("some error"))
Expand Down
1 change: 1 addition & 0 deletions xds/internal/balancer/outlierdetection/subconn_wrapper.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import (
// whether or not this SubConn is ejected.
type subConnWrapper struct {
balancer.SubConn
listener func(balancer.SubConnState)

// addressInfo is a pointer to the subConnWrapper's corresponding address
// map entry, if the map entry exists.
Expand Down