github.com/hxx258456/ccgo@v0.0.5-0.20230213014102-48b35f46f66f/grpc/xds/internal/balancer/clusterresolver/resource_resolver_dns.go (about) 1 /* 2 * 3 * Copyright 2021 gRPC authors. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 */ 18 19 package clusterresolver 20 21 import ( 22 "fmt" 23 24 "github.com/hxx258456/ccgo/grpc/resolver" 25 "github.com/hxx258456/ccgo/grpc/serviceconfig" 26 ) 27 28 var ( 29 newDNS = func(target resolver.Target, cc resolver.ClientConn, opts resolver.BuildOptions) (resolver.Resolver, error) { 30 // The dns resolver is registered by the grpc package. So, this call to 31 // resolver.Get() is never expected to return nil. 32 return resolver.Get("dns").Build(target, cc, opts) 33 } 34 ) 35 36 // dnsDiscoveryMechanism watches updates for the given DNS hostname. 37 // 38 // It implements resolver.ClientConn interface to work with the DNS resolver. 39 type dnsDiscoveryMechanism struct { 40 target string 41 topLevelResolver *resourceResolver 42 r resolver.Resolver 43 44 addrs []string 45 updateReceived bool 46 } 47 48 func newDNSResolver(target string, topLevelResolver *resourceResolver) *dnsDiscoveryMechanism { 49 ret := &dnsDiscoveryMechanism{ 50 target: target, 51 topLevelResolver: topLevelResolver, 52 } 53 r, err := newDNS(resolver.Target{Scheme: "dns", Endpoint: target}, ret, resolver.BuildOptions{}) 54 if err != nil { 55 select { 56 case <-topLevelResolver.updateChannel: 57 default: 58 } 59 topLevelResolver.updateChannel <- &resourceUpdate{err: err} 60 } 61 ret.r = r 62 return ret 63 } 64 65 func (dr *dnsDiscoveryMechanism) lastUpdate() (interface{}, bool) { 66 if !dr.updateReceived { 67 return nil, false 68 } 69 return dr.addrs, true 70 } 71 72 func (dr *dnsDiscoveryMechanism) resolveNow() { 73 dr.r.ResolveNow(resolver.ResolveNowOptions{}) 74 } 75 76 func (dr *dnsDiscoveryMechanism) stop() { 77 dr.r.Close() 78 } 79 80 // dnsDiscoveryMechanism needs to implement resolver.ClientConn interface to receive 81 // updates from the real DNS resolver. 82 83 func (dr *dnsDiscoveryMechanism) UpdateState(state resolver.State) error { 84 dr.topLevelResolver.mu.Lock() 85 defer dr.topLevelResolver.mu.Unlock() 86 addrs := make([]string, len(state.Addresses)) 87 for i, a := range state.Addresses { 88 addrs[i] = a.Addr 89 } 90 dr.addrs = addrs 91 dr.updateReceived = true 92 dr.topLevelResolver.generate() 93 return nil 94 } 95 96 func (dr *dnsDiscoveryMechanism) ReportError(err error) { 97 select { 98 case <-dr.topLevelResolver.updateChannel: 99 default: 100 } 101 dr.topLevelResolver.updateChannel <- &resourceUpdate{err: err} 102 } 103 104 func (dr *dnsDiscoveryMechanism) NewAddress(addresses []resolver.Address) { 105 dr.UpdateState(resolver.State{Addresses: addresses}) 106 } 107 108 func (dr *dnsDiscoveryMechanism) NewServiceConfig(string) { 109 // This method is deprecated, and service config isn't supported. 110 } 111 112 func (dr *dnsDiscoveryMechanism) ParseServiceConfig(string) *serviceconfig.ParseResult { 113 return &serviceconfig.ParseResult{Err: fmt.Errorf("service config not supported")} 114 }