github.com/lingyao2333/mo-zero@v1.4.1/zrpc/resolver/internal/kube/eventhandler.go (about) 1 package kube 2 3 import ( 4 "sync" 5 6 "github.com/lingyao2333/mo-zero/core/lang" 7 "github.com/lingyao2333/mo-zero/core/logx" 8 v1 "k8s.io/api/core/v1" 9 ) 10 11 // EventHandler is ResourceEventHandler implementation. 12 type EventHandler struct { 13 update func([]string) 14 endpoints map[string]lang.PlaceholderType 15 lock sync.Mutex 16 } 17 18 // NewEventHandler returns an EventHandler. 19 func NewEventHandler(update func([]string)) *EventHandler { 20 return &EventHandler{ 21 update: update, 22 endpoints: make(map[string]lang.PlaceholderType), 23 } 24 } 25 26 // OnAdd handles the endpoints add events. 27 func (h *EventHandler) OnAdd(obj interface{}) { 28 endpoints, ok := obj.(*v1.Endpoints) 29 if !ok { 30 logx.Errorf("%v is not an object with type *v1.Endpoints", obj) 31 return 32 } 33 34 h.lock.Lock() 35 defer h.lock.Unlock() 36 37 var changed bool 38 for _, sub := range endpoints.Subsets { 39 for _, point := range sub.Addresses { 40 if _, ok := h.endpoints[point.IP]; !ok { 41 h.endpoints[point.IP] = lang.Placeholder 42 changed = true 43 } 44 } 45 } 46 47 if changed { 48 h.notify() 49 } 50 } 51 52 // OnDelete handles the endpoints delete events. 53 func (h *EventHandler) OnDelete(obj interface{}) { 54 endpoints, ok := obj.(*v1.Endpoints) 55 if !ok { 56 logx.Errorf("%v is not an object with type *v1.Endpoints", obj) 57 return 58 } 59 60 h.lock.Lock() 61 defer h.lock.Unlock() 62 63 var changed bool 64 for _, sub := range endpoints.Subsets { 65 for _, point := range sub.Addresses { 66 if _, ok := h.endpoints[point.IP]; ok { 67 delete(h.endpoints, point.IP) 68 changed = true 69 } 70 } 71 } 72 73 if changed { 74 h.notify() 75 } 76 } 77 78 // OnUpdate handles the endpoints update events. 79 func (h *EventHandler) OnUpdate(oldObj, newObj interface{}) { 80 oldEndpoints, ok := oldObj.(*v1.Endpoints) 81 if !ok { 82 logx.Errorf("%v is not an object with type *v1.Endpoints", oldObj) 83 return 84 } 85 86 newEndpoints, ok := newObj.(*v1.Endpoints) 87 if !ok { 88 logx.Errorf("%v is not an object with type *v1.Endpoints", newObj) 89 return 90 } 91 92 if oldEndpoints.ResourceVersion == newEndpoints.ResourceVersion { 93 return 94 } 95 96 h.Update(newEndpoints) 97 } 98 99 // Update updates the endpoints. 100 func (h *EventHandler) Update(endpoints *v1.Endpoints) { 101 h.lock.Lock() 102 defer h.lock.Unlock() 103 104 old := h.endpoints 105 h.endpoints = make(map[string]lang.PlaceholderType) 106 for _, sub := range endpoints.Subsets { 107 for _, point := range sub.Addresses { 108 h.endpoints[point.IP] = lang.Placeholder 109 } 110 } 111 112 if diff(old, h.endpoints) { 113 h.notify() 114 } 115 } 116 117 func (h *EventHandler) notify() { 118 targets := make([]string, 0, len(h.endpoints)) 119 120 for k := range h.endpoints { 121 targets = append(targets, k) 122 } 123 124 h.update(targets) 125 } 126 127 func diff(o, n map[string]lang.PlaceholderType) bool { 128 if len(o) != len(n) { 129 return true 130 } 131 132 for k := range o { 133 if _, ok := n[k]; !ok { 134 return true 135 } 136 } 137 138 return false 139 }