github.com/projecteru2/core@v0.0.0-20240321043226-06bcc1c23f58/client/resolver/eru/resolver.go (about) 1 package eru 2 3 import ( 4 "context" 5 "strings" 6 7 "github.com/projecteru2/core/client/servicediscovery" 8 "github.com/projecteru2/core/log" 9 "github.com/projecteru2/core/types" 10 11 "google.golang.org/grpc/resolver" 12 ) 13 14 // Resolver for target eru://{addr} 15 type Resolver struct { 16 cc resolver.ClientConn 17 cancel context.CancelFunc 18 discovery servicediscovery.ServiceDiscovery 19 } 20 21 // New Resolver 22 func New(cc resolver.ClientConn, endpoint string, authority string) *Resolver { 23 var username, password string 24 if authority != "" { 25 parts := strings.Split(authority, ":") 26 username, password = strings.TrimLeft(parts[0], "@"), parts[1] 27 } 28 authConfig := types.AuthConfig{Username: username, Password: password} 29 r := &Resolver{ 30 cc: cc, 31 discovery: servicediscovery.New(endpoint, authConfig), 32 } 33 cc.UpdateState(resolver.State{Addresses: []resolver.Address{{Addr: endpoint}}}) //nolint 34 go r.sync(context.TODO()) 35 return r 36 } 37 38 // ResolveNow for interface 39 func (r *Resolver) ResolveNow(_ resolver.ResolveNowOptions) {} 40 41 // Close for interface 42 func (r *Resolver) Close() { 43 r.cancel() 44 } 45 46 func (r *Resolver) sync(ctx context.Context) { 47 ctx, r.cancel = context.WithCancel(ctx) 48 defer r.cancel() 49 logger := log.WithFunc("resolver.sync") 50 logger.Debug(ctx, "start sync service discovery") 51 52 ch, err := r.discovery.Watch(ctx) 53 if err != nil { 54 logger.Error(ctx, err, "failed to watch service status") 55 return 56 } 57 for { 58 select { 59 case <-ctx.Done(): 60 logger.Error(ctx, ctx.Err(), "watch interrupted") 61 return 62 case endpoints, ok := <-ch: 63 if !ok { 64 logger.Info(ctx, nil, "watch closed") 65 return 66 } 67 68 var addresses []resolver.Address 69 for _, ep := range endpoints { 70 addresses = append(addresses, resolver.Address{Addr: ep}) 71 } 72 r.cc.UpdateState(resolver.State{Addresses: addresses}) //nolint 73 } 74 } 75 76 }