Skip to content

Commit 30bcf33

Browse files
author
Fabian Holler
committed
fix: UpdateState() not called when service becomes unresolvable
When a service was resolved and became unreachable, cc.UpdateState() was not called. The clientConn continued to use the afore resolved addresses.
1 parent 41c7b02 commit 30bcf33

2 files changed

Lines changed: 57 additions & 1 deletion

File tree

consul/resolver.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,8 @@ func (c *consulResolver) watcher() {
121121
// data newer then the passed opts.WaitIndex is available.
122122
// We check if the returned addrs changed to not call
123123
// cc.UpdateState() unnecessary for unchanged addresses.
124-
if len(addrs) == 0 || reflect.DeepEqual(addrs, lastAddrs) {
124+
if (len(addrs) == 0 && len(lastAddrs) == 0) ||
125+
reflect.DeepEqual(addrs, lastAddrs) {
125126
// sleep a bit to prevent that query() is
126127
// called in a tight-loop if the consul server
127128
// returns multiple time immediately, despite

consul/resolver_test.go

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,61 @@ func TestResolveAddrChange(t *testing.T) {
313313
r.Close()
314314
}
315315

316+
func TestResolveAddrChangesToUnresolvable(t *testing.T) {
317+
health := &consulMockHealthClient{}
318+
cleanup := replaceCreateHealthClientFn(
319+
func(cfg *consul.Config) (consulHealthEndpoint, error) {
320+
return health, nil
321+
},
322+
)
323+
defer cleanup()
324+
325+
addrs1 := []*consul.AgentService{
326+
&consul.AgentService{
327+
Address: "localhost",
328+
Port: 5678,
329+
},
330+
}
331+
addrs2 := []*consul.AgentService{}
332+
333+
cc := testClientConn{}
334+
newAddressCallCnt := cc.getNewAddressCallCnt()
335+
target := resolver.Target{Endpoint: "user-service"}
336+
b := NewBuilder()
337+
338+
health.setResolveAddrs(addrs1)
339+
340+
r, err := b.Build(target, &cc, resolver.BuildOptions{})
341+
if err != nil {
342+
t.Fatal("Build() failed:", err.Error())
343+
}
344+
345+
r.ResolveNow(resolver.ResolveNowOptions{})
346+
347+
for newAddressCallCnt == cc.getNewAddressCallCnt() {
348+
time.Sleep(time.Millisecond)
349+
}
350+
351+
resolvedAddrs := cc.getAddrs()
352+
if !cmpResolveResults(resolvedAddrs, addrs1) {
353+
t.Errorf("resolved address '%+v', expected: '%+v'", resolvedAddrs, addrs1)
354+
}
355+
356+
newAddressCallCnt = cc.getNewAddressCallCnt()
357+
health.setResolveAddrs(addrs2)
358+
r.ResolveNow(resolver.ResolveNowOptions{})
359+
for newAddressCallCnt == cc.getNewAddressCallCnt() {
360+
time.Sleep(time.Millisecond)
361+
}
362+
363+
resolvedAddrs = cc.getAddrs()
364+
if !cmpResolveResults(resolvedAddrs, addrs2) {
365+
t.Errorf("resolved address after change '%+v', expected: '%+v'", resolvedAddrs, addrs1)
366+
}
367+
368+
r.Close()
369+
}
370+
316371
func TestErrorIsReportedOnQueryErrors(t *testing.T) {
317372
queryErr := errors.New("query failed")
318373
health := &consulMockHealthClient{err: queryErr}

0 commit comments

Comments
 (0)