dubbo.apache.org/dubbo-go/v3@v3.1.1/registry/polaris/core.go (about) 1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. 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 package polaris 19 20 import ( 21 "sync" 22 "time" 23 ) 24 25 import ( 26 api "github.com/polarismesh/polaris-go" 27 internalapi "github.com/polarismesh/polaris-go/api" 28 "github.com/polarismesh/polaris-go/pkg/model" 29 ) 30 31 import ( 32 "dubbo.apache.org/dubbo-go/v3/config_center" 33 "dubbo.apache.org/dubbo-go/v3/remoting" 34 ) 35 36 type item func(remoting.EventType, []model.Instance) 37 38 type PolarisServiceWatcher struct { 39 consumer api.ConsumerAPI 40 subscribeParam *api.WatchServiceRequest 41 lock *sync.RWMutex 42 subscribers []item 43 execOnce *sync.Once 44 } 45 46 // newPolarisWatcher create PolarisServiceWatcher to do watch service action 47 func newPolarisWatcher(param *api.WatchServiceRequest, consumer api.ConsumerAPI) (*PolarisServiceWatcher, error) { 48 watcher := &PolarisServiceWatcher{ 49 subscribeParam: param, 50 consumer: consumer, 51 lock: &sync.RWMutex{}, 52 subscribers: make([]item, 0), 53 execOnce: &sync.Once{}, 54 } 55 return watcher, nil 56 } 57 58 // AddSubscriber add subscriber into watcher's subscribers 59 func (watcher *PolarisServiceWatcher) AddSubscriber(subscriber func(remoting.EventType, []model.Instance)) { 60 61 watcher.lock.Lock() 62 watcher.lazyRun() 63 defer watcher.lock.Unlock() 64 65 watcher.subscribers = append(watcher.subscribers, subscriber) 66 } 67 68 // lazyRun Delayed execution, only triggered when AddSubscriber is called, and will only be executed once 69 func (watcher *PolarisServiceWatcher) lazyRun() { 70 watcher.execOnce.Do(func() { 71 go watcher.startWatch() 72 }) 73 } 74 75 // startWatch start run work to watch target service by polaris 76 func (watcher *PolarisServiceWatcher) startWatch() { 77 for { 78 resp, err := watcher.consumer.WatchService(watcher.subscribeParam) 79 if err != nil { 80 time.Sleep(time.Duration(500 * time.Millisecond)) 81 continue 82 } 83 watcher.notifyAllSubscriber(&config_center.ConfigChangeEvent{ 84 Value: resp.GetAllInstancesResp.Instances, 85 ConfigType: remoting.EventTypeAdd, 86 }) 87 88 for { 89 select { 90 case event := <-resp.EventChannel: 91 eType := event.GetSubScribeEventType() 92 if eType == internalapi.EventInstance { 93 insEvent := event.(*model.InstanceEvent) 94 95 if insEvent.AddEvent != nil { 96 watcher.notifyAllSubscriber(&config_center.ConfigChangeEvent{ 97 Value: insEvent.AddEvent.Instances, 98 ConfigType: remoting.EventTypeAdd, 99 }) 100 } 101 if insEvent.UpdateEvent != nil { 102 instances := make([]model.Instance, len(insEvent.UpdateEvent.UpdateList)) 103 for i := range insEvent.UpdateEvent.UpdateList { 104 instances[i] = insEvent.UpdateEvent.UpdateList[i].After 105 } 106 watcher.notifyAllSubscriber(&config_center.ConfigChangeEvent{ 107 Value: instances, 108 ConfigType: remoting.EventTypeUpdate, 109 }) 110 } 111 if insEvent.DeleteEvent != nil { 112 watcher.notifyAllSubscriber(&config_center.ConfigChangeEvent{ 113 Value: insEvent.DeleteEvent.Instances, 114 ConfigType: remoting.EventTypeDel, 115 }) 116 } 117 } 118 } 119 } 120 121 } 122 } 123 124 // notifyAllSubscriber notify config_center.ConfigChangeEvent to all subscriber 125 func (watcher *PolarisServiceWatcher) notifyAllSubscriber(event *config_center.ConfigChangeEvent) { 126 watcher.lock.RLock() 127 defer watcher.lock.RUnlock() 128 129 for i := 0; i < len(watcher.subscribers); i++ { 130 subscriber := watcher.subscribers[i] 131 subscriber(event.ConfigType, event.Value.([]model.Instance)) 132 } 133 134 }