github.com/annwntech/go-micro/v2@v2.9.5/router/watcher.go (about) 1 package router 2 3 import ( 4 "errors" 5 "sync" 6 "time" 7 ) 8 9 var ( 10 // ErrWatcherStopped is returned when routing table watcher has been stopped 11 ErrWatcherStopped = errors.New("watcher stopped") 12 ) 13 14 // EventType defines routing table event 15 type EventType int 16 17 const ( 18 // Create is emitted when a new route has been created 19 Create EventType = iota 20 // Delete is emitted when an existing route has been deleted 21 Delete 22 // Update is emitted when an existing route has been updated 23 Update 24 ) 25 26 // String returns human readable event type 27 func (t EventType) String() string { 28 switch t { 29 case Create: 30 return "create" 31 case Delete: 32 return "delete" 33 case Update: 34 return "update" 35 default: 36 return "unknown" 37 } 38 } 39 40 // Event is returned by a call to Next on the watcher. 41 type Event struct { 42 // Unique id of the event 43 Id string 44 // Type defines type of event 45 Type EventType 46 // Timestamp is event timestamp 47 Timestamp time.Time 48 // Route is table route 49 Route Route 50 } 51 52 // Watcher defines routing table watcher interface 53 // Watcher returns updates to the routing table 54 type Watcher interface { 55 // Next is a blocking call that returns watch result 56 Next() (*Event, error) 57 // Chan returns event channel 58 Chan() (<-chan *Event, error) 59 // Stop stops watcher 60 Stop() 61 } 62 63 // WatchOption is used to define what routes to watch in the table 64 type WatchOption func(*WatchOptions) 65 66 // WatchOptions are table watcher options 67 // TODO: expand the options to watch based on other criteria 68 type WatchOptions struct { 69 // Service allows to watch specific service routes 70 Service string 71 } 72 73 // WatchService sets what service routes to watch 74 // Service is the microservice name 75 func WatchService(s string) WatchOption { 76 return func(o *WatchOptions) { 77 o.Service = s 78 } 79 } 80 81 // tableWatcher implements routing table Watcher 82 type tableWatcher struct { 83 sync.RWMutex 84 id string 85 opts WatchOptions 86 resChan chan *Event 87 done chan struct{} 88 } 89 90 // Next returns the next noticed action taken on table 91 // TODO: right now we only allow to watch particular service 92 func (w *tableWatcher) Next() (*Event, error) { 93 for { 94 select { 95 case res := <-w.resChan: 96 switch w.opts.Service { 97 case res.Route.Service, "*": 98 return res, nil 99 default: 100 continue 101 } 102 case <-w.done: 103 return nil, ErrWatcherStopped 104 } 105 } 106 } 107 108 // Chan returns watcher events channel 109 func (w *tableWatcher) Chan() (<-chan *Event, error) { 110 return w.resChan, nil 111 } 112 113 // Stop stops routing table watcher 114 func (w *tableWatcher) Stop() { 115 w.Lock() 116 defer w.Unlock() 117 118 select { 119 case <-w.done: 120 return 121 default: 122 close(w.done) 123 } 124 }