-
Notifications
You must be signed in to change notification settings - Fork 1
/
dns_resolver.go
84 lines (71 loc) · 1.61 KB
/
dns_resolver.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
package discov
import (
"context"
"fmt"
"google.golang.org/grpc/balancer/roundrobin"
"google.golang.org/grpc/resolver"
"net"
"sync"
"time"
)
// dnsResolver is an implementation of gRPC Resolver interface.
type dnsResolver struct {
dnsName string
port int
resolver *net.Resolver
pollingInterval time.Duration
ctx context.Context
cancel context.CancelFunc
wg sync.WaitGroup
rn chan struct{}
cc resolver.ClientConn
disableSrvCfg bool
}
func (r *dnsResolver) ResolveNow(resolver.ResolveNowOptions) {
select {
case r.rn <- struct{}{}:
default:
}
}
func (r *dnsResolver) Close() {
r.cancel()
r.wg.Wait()
}
func (r *dnsResolver) watcher() {
defer r.wg.Done()
ticker := time.NewTicker(r.pollingInterval)
for {
select {
case <-r.ctx.Done():
ticker.Stop()
return
case <-ticker.C:
case <-r.rn:
}
r.resolve()
}
}
func (r *dnsResolver) resolve() {
stat := resolver.State{}
ctx, cancel := context.WithTimeout(r.ctx, time.Second*3)
defer cancel()
addrs, err := r.resolver.LookupHost(ctx, r.dnsName)
if err != nil {
r.cc.ReportError(fmt.Errorf("dns resolver lookup host failed: %v", err))
return
}
var newAddrs []resolver.Address
for _, addr := range addrs {
addr, ok := formatIP(addr)
if !ok {
continue
}
addr = fmt.Sprintf("%s:%d", addr, r.port)
newAddrs = append(newAddrs, resolver.Address{Addr: addr})
}
stat.Addresses = newAddrs
if !r.disableSrvCfg {
stat.ServiceConfig = r.cc.ParseServiceConfig(fmt.Sprintf(`{"LoadBalancingPolicy": %q}`, roundrobin.Name))
}
r.cc.UpdateState(stat)
}