...
1 package client
2
3 import (
4 "flag"
5 "fmt"
6 "golang.conradwood.net/apis/registry"
7 "golang.conradwood.net/go-easyops/cmdline"
8 "golang.conradwood.net/go-easyops/utils"
9 "google.golang.org/grpc/connectivity"
10 "sync"
11 "time"
12 )
13
14 const (
15 REFRESH = time.Duration(5) * time.Second
16 )
17
18 var (
19 debug_custom_resolver = flag.Bool("ge_debug_custom_fancy_resolver", false, "debug the custom fancy resolver, if any are being used")
20 custom_fancyadrlist_lock sync.Mutex
21 )
22
23 type custom_fancy_addresslist struct {
24 fal *FancyAddressList
25 resolver func(registryadr, servicename string) ([]*registry.Target, error)
26 }
27
28
32 func NewFancyAddressListWithResolver(servicename string, resolver func(registryadr, servicename string) ([]*registry.Target, error)) (*FancyAddressList, error) {
33 fal := &FancyAddressList{Name: servicename}
34 cfa := &custom_fancy_addresslist{fal: fal, resolver: resolver}
35 targets, err := resolver(cmdline.GetClientRegistryAddress(), servicename)
36 if err != nil {
37 return nil, err
38 }
39 for _, fa := range targets_to_fancyadr(targets) {
40 fal.Add(fa)
41 }
42 go cfa.custom_fal_updater(REFRESH)
43 return fal, nil
44 }
45
46 func (cfa *custom_fancy_addresslist) custom_fal_updater(refresh time.Duration) {
47 for {
48 time.Sleep(refresh)
49 targets, err := cfa.resolver(cmdline.GetClientRegistryAddress(), cfa.fal.Name)
50 if err != nil {
51 fmt.Printf("[go-easyops] custom fancyaddresslist resolver failed: %s\n", err)
52 continue
53 }
54 cfa.debugf("got %d targets from resolver\n", len(targets))
55 fas := targets_to_fancyadr(targets)
56 cfa.debugf("got %d fancyaddress from %d targets from resolver\n", len(fas), len(targets))
57 ac := utils.CompareArray(fas, cfa.fal.addresses, func(i, j int) bool {
58 return fas[i].Key() == cfa.fal.addresses[j].Key()
59 })
60 for _, fa_idx := range ac.ElementsIn1ButNot2() {
61 cfa.debugf("adding %s\n", fas[fa_idx])
62 cfa.fal.Add(fas[fa_idx])
63 }
64 for _, fa_idx := range ac.ElementsIn2ButNot1() {
65 cfa.debugf("removing %s\n", cfa.fal.addresses[fa_idx])
66 cfa.fal.remove(cfa.fal.addresses[fa_idx])
67 }
68 }
69 }
70 func (cfa *custom_fancy_addresslist) debugf(format string, args ...interface{}) {
71 if !*debug_custom_resolver {
72 return
73 }
74 s := fmt.Sprintf(format, args...)
75 fmt.Printf("[go-easyops] fancyaddresslist: %s", s)
76 }
77 func targets_to_fancyadr(targets []*registry.Target) []*FancyAddr {
78 var res []*FancyAddr
79 for _, t := range targets {
80 if !hasApi(t.ApiType, registry.Apitype_grpc) {
81
82 continue
83 }
84 fa := &FancyAddr{state: connectivity.Ready,
85 addr: fmt.Sprintf("%s:%d", t.IP, t.Port),
86 Target: t,
87 }
88 res = append(res, fa)
89 }
90
91 return res
92 }
93
View as plain text