...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package resolver
16
17 import (
18 "go.etcd.io/etcd/client/v3/internal/endpoint"
19 "google.golang.org/grpc/resolver"
20 "google.golang.org/grpc/resolver/manual"
21 "google.golang.org/grpc/serviceconfig"
22 )
23
24 const (
25 Schema = "etcd-endpoints"
26 )
27
28
29
30 type EtcdManualResolver struct {
31 *manual.Resolver
32 endpoints []string
33 serviceConfig *serviceconfig.ParseResult
34 }
35
36 func New(endpoints ...string) *EtcdManualResolver {
37 r := manual.NewBuilderWithScheme(Schema)
38 return &EtcdManualResolver{Resolver: r, endpoints: endpoints, serviceConfig: nil}
39 }
40
41
42 func (r *EtcdManualResolver) Build(target resolver.Target, cc resolver.ClientConn, opts resolver.BuildOptions) (resolver.Resolver, error) {
43 r.serviceConfig = cc.ParseServiceConfig(`{"loadBalancingPolicy": "round_robin"}`)
44 if r.serviceConfig.Err != nil {
45 return nil, r.serviceConfig.Err
46 }
47 res, err := r.Resolver.Build(target, cc, opts)
48 if err != nil {
49 return nil, err
50 }
51
52 r.updateState()
53 return res, nil
54 }
55
56 func (r *EtcdManualResolver) SetEndpoints(endpoints []string) {
57 r.endpoints = endpoints
58 r.updateState()
59 }
60
61 func (r EtcdManualResolver) updateState() {
62 if r.CC != nil {
63 addresses := make([]resolver.Address, len(r.endpoints))
64 for i, ep := range r.endpoints {
65 addr, serverName := endpoint.Interpret(ep)
66 addresses[i] = resolver.Address{Addr: addr, ServerName: serverName}
67 }
68 state := resolver.State{
69 Addresses: addresses,
70 ServiceConfig: r.serviceConfig,
71 }
72 r.UpdateState(state)
73 }
74 }
75
View as plain text