/
resolver.go
96 lines (82 loc) · 2 KB
/
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
85
86
87
88
89
90
91
92
93
94
95
96
package registry
import (
"fmt"
"sync"
"github.com/lujingwei002/gira"
"google.golang.org/grpc/resolver"
)
// grpc resolver
const (
PeerScheme string = "peer"
)
func formatPeerUrl(fullName string) string {
return fmt.Sprintf("%s:///%s", PeerScheme, fullName)
}
type peer_resolver_builder struct {
r *Registry
resolvers sync.Map
}
type peer_resolver struct {
cc resolver.ClientConn
builder *peer_resolver_builder
reg *Registry
fullName string
Address string
}
func (builder *peer_resolver_builder) Build(target resolver.Target, cc resolver.ClientConn, opts resolver.BuildOptions) (resolver.Resolver, error) {
r := &peer_resolver{
cc: cc,
reg: builder.r,
builder: builder,
fullName: target.Endpoint(),
}
if last, loaded := builder.resolvers.LoadOrStore(r.fullName, r); loaded {
r = last.(*peer_resolver)
addr := resolver.Address{
Addr: r.Address,
}
cc.UpdateState(resolver.State{
Addresses: []resolver.Address{addr},
})
return r, nil
} else {
if peer := r.reg.peerRegistry.getPeer(r.reg, r.fullName); peer == nil {
return r, nil
} else {
r.Address = peer.Address
addr := resolver.Address{
Addr: r.Address,
}
cc.UpdateState(resolver.State{
Addresses: []resolver.Address{addr},
})
return r, nil
}
}
}
func (builder *peer_resolver_builder) onPeerUpdate(reg *Registry, peer *gira.Peer) error {
if last, ok := builder.resolvers.Load(peer.FullName); !ok {
return nil
} else {
peerResolver := last.(*peer_resolver)
return peerResolver.onPeerUpdate(reg, peer)
}
}
func (builder *peer_resolver_builder) Scheme() string {
return PeerScheme
}
func (r *peer_resolver) ResolveNow(o resolver.ResolveNowOptions) {
}
func (r *peer_resolver) Close() {
r.builder.resolvers.Delete(r.fullName)
}
func (r *peer_resolver) onPeerUpdate(reg *Registry, peer *gira.Peer) error {
r.Address = peer.Address
addr := resolver.Address{
Addr: r.Address,
}
r.cc.UpdateState(resolver.State{
Addresses: []resolver.Address{addr},
})
return nil
}