mirror of
https://github.com/go-kit/kit.git
synced 2025-07-17 01:12:38 +02:00
util/conn: reconnect when initial Dial fails
This commit is contained in:
@ -67,11 +67,16 @@ func (m *Manager) Put(err error) {
|
||||
func (m *Manager) loop() {
|
||||
var (
|
||||
conn = dial(m.dialer, m.network, m.address, m.logger) // may block slightly
|
||||
connc = make(chan net.Conn)
|
||||
connc = make(chan net.Conn, 1)
|
||||
reconnectc <-chan time.Time // initially nil
|
||||
backoff = time.Second
|
||||
)
|
||||
|
||||
// If the initial dial fails, we need to trigger a reconnect via the loop
|
||||
// body, below. If we did this in a goroutine, we would race on the conn
|
||||
// variable. So we use a buffered chan instead.
|
||||
connc <- conn
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-reconnectc:
|
||||
|
@ -91,6 +91,39 @@ func TestManager(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestIssue292(t *testing.T) {
|
||||
// The util/conn.Manager won't attempt to reconnect to the provided endpoint
|
||||
// if the endpoint is initially unavailable (e.g. dial tcp :8080:
|
||||
// getsockopt: connection refused). If the endpoint is up when
|
||||
// conn.NewManager is called and then goes down/up, it reconnects just fine.
|
||||
|
||||
var (
|
||||
tickc = make(chan time.Time)
|
||||
after = func(time.Duration) <-chan time.Time { return tickc }
|
||||
dialconn = net.Conn(nil)
|
||||
dialerr = errors.New("fail")
|
||||
dialer = func(string, string) (net.Conn, error) { return dialconn, dialerr }
|
||||
mgr = NewManager(dialer, "netw", "addr", after, log.NewNopLogger())
|
||||
)
|
||||
|
||||
if conn := mgr.Take(); conn != nil {
|
||||
t.Fatal("first Take should have yielded nil conn, but didn't")
|
||||
}
|
||||
|
||||
dialconn, dialerr = &mockConn{}, nil
|
||||
select {
|
||||
case tickc <- time.Now():
|
||||
case <-time.After(time.Second):
|
||||
t.Fatal("manager isn't listening for a tick, despite a failed dial")
|
||||
}
|
||||
|
||||
if !within(time.Second, func() bool {
|
||||
return mgr.Take() != nil
|
||||
}) {
|
||||
t.Fatal("second Take should have yielded good conn, but didn't")
|
||||
}
|
||||
}
|
||||
|
||||
type mockConn struct {
|
||||
rd, wr uint64
|
||||
}
|
||||
|
Reference in New Issue
Block a user