-
Notifications
You must be signed in to change notification settings - Fork 4.3k
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
Fix connectivity state transitions when dialing #1596
Changes from 6 commits
8e55d70
a8e2429
723d333
daf8b1f
3ba27f2
01631b1
f92b609
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -704,7 +704,7 @@ func (cc *ClientConn) removeAddrConn(ac *addrConn, err error) { | |
// It does nothing if the ac is not IDLE. | ||
// TODO(bar) Move this to the addrConn section. | ||
// This was part of resetAddrConn, keep it here to make the diff look clean. | ||
func (ac *addrConn) connect(block bool) error { | ||
func (ac *addrConn) connect() error { | ||
ac.mu.Lock() | ||
if ac.state == connectivity.Shutdown { | ||
ac.mu.Unlock() | ||
|
@@ -718,32 +718,18 @@ func (ac *addrConn) connect(block bool) error { | |
ac.cc.handleSubConnStateChange(ac.acbw, ac.state) | ||
ac.mu.Unlock() | ||
|
||
if block { | ||
// Start a goroutine connecting to the server asynchronously. | ||
go func() { | ||
if err := ac.resetTransport(); err != nil { | ||
grpclog.Warningf("Failed to dial %s: %v; please retry.", ac.addrs[0].Addr, err) | ||
if err != errConnClosing { | ||
// Keep this ac in cc.conns, to get the reason it's torn down. | ||
ac.tearDown(err) | ||
} | ||
if e, ok := err.(transport.ConnectionError); ok && !e.Temporary() { | ||
return e.Origin() | ||
} | ||
return err | ||
return | ||
} | ||
// Start to monitor the error status of transport. | ||
go ac.transportMonitor() | ||
} else { | ||
// Start a goroutine connecting to the server asynchronously. | ||
go func() { | ||
if err := ac.resetTransport(); err != nil { | ||
grpclog.Warningf("Failed to dial %s: %v; please retry.", ac.addrs[0].Addr, err) | ||
if err != errConnClosing { | ||
// Keep this ac in cc.conns, to get the reason it's torn down. | ||
ac.tearDown(err) | ||
} | ||
return | ||
} | ||
ac.transportMonitor() | ||
}() | ||
} | ||
ac.transportMonitor() | ||
}() | ||
return nil | ||
} | ||
|
||
|
@@ -904,15 +890,17 @@ func (ac *addrConn) errorf(format string, a ...interface{}) { | |
|
||
// resetTransport recreates a transport to the address for ac. The old | ||
// transport will close itself on error or when the clientconn is closed. | ||
// | ||
// The connectivity state of ac will be set to TransientFailure if it's not | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this accurate? It seems that There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The state is set by |
||
// first time doing resetTransport. | ||
// | ||
// TODO(bar) make sure all state transitions are valid. | ||
func (ac *addrConn) resetTransport() error { | ||
ac.mu.Lock() | ||
if ac.state == connectivity.Shutdown { | ||
ac.mu.Unlock() | ||
return errConnClosing | ||
} | ||
ac.state = connectivity.TransientFailure | ||
ac.cc.handleSubConnStateChange(ac.acbw, ac.state) | ||
if ac.ready != nil { | ||
close(ac.ready) | ||
ac.ready = nil | ||
|
@@ -936,8 +924,10 @@ func (ac *addrConn) resetTransport() error { | |
return errConnClosing | ||
} | ||
ac.printf("connecting") | ||
ac.state = connectivity.Connecting | ||
ac.cc.handleSubConnStateChange(ac.acbw, ac.state) | ||
if ac.state != connectivity.Connecting { | ||
ac.state = connectivity.Connecting | ||
ac.cc.handleSubConnStateChange(ac.acbw, ac.state) | ||
} | ||
// copy ac.addrs in case of race | ||
addrsIter := make([]resolver.Address, len(ac.addrs)) | ||
copy(addrsIter, ac.addrs) | ||
|
@@ -1031,6 +1021,11 @@ func (ac *addrConn) transportMonitor() { | |
ac.adjustParams(t.GetGoAwayReason()) | ||
default: | ||
} | ||
ac.mu.Lock() | ||
ac.state = connectivity.TransientFailure | ||
ac.cc.handleSubConnStateChange(ac.acbw, ac.state) | ||
ac.curAddr = resolver.Address{} | ||
ac.mu.Unlock() | ||
if err := ac.resetTransport(); err != nil { | ||
ac.mu.Lock() | ||
ac.printf("transport exiting: %v", err) | ||
|
@@ -1102,7 +1097,7 @@ func (ac *addrConn) getReadyTransport() (transport.ClientTransport, bool) { | |
ac.mu.Unlock() | ||
// Trigger idle ac to connect. | ||
if idle { | ||
ac.connect(false) | ||
ac.connect() | ||
} | ||
return nil, false | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this test is called
TestInvokeCancelClosedNonFailFast
- did you mean to make this change?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch. Reverted.