gitee.com/liuxuezhan/go-micro-v1.18.0@v1.0.0/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 // Type defines type of event 43 Type EventType 44 // Timestamp is event timestamp 45 Timestamp time.Time 46 // Route is table route 47 Route Route 48 } 49 50 // Watcher defines routing table watcher interface 51 // Watcher returns updates to the routing table 52 type Watcher interface { 53 // Next is a blocking call that returns watch result 54 Next() (*Event, error) 55 // Chan returns event channel 56 Chan() (<-chan *Event, error) 57 // Stop stops watcher 58 Stop() 59 } 60 61 // WatchOption is used to define what routes to watch in the table 62 type WatchOption func(*WatchOptions) 63 64 // WatchOptions are table watcher options 65 // TODO: expand the options to watch based on other criteria 66 type WatchOptions struct { 67 // Service allows to watch specific service routes 68 Service string 69 } 70 71 // WatchService sets what service routes to watch 72 // Service is the microservice name 73 func WatchService(s string) WatchOption { 74 return func(o *WatchOptions) { 75 o.Service = s 76 } 77 } 78 79 // tableWatcher implements routing table Watcher 80 type tableWatcher struct { 81 sync.RWMutex 82 id string 83 opts WatchOptions 84 resChan chan *Event 85 done chan struct{} 86 } 87 88 // Next returns the next noticed action taken on table 89 // TODO: right now we only allow to watch particular service 90 func (w *tableWatcher) Next() (*Event, error) { 91 for { 92 select { 93 case res := <-w.resChan: 94 switch w.opts.Service { 95 case res.Route.Service, "*": 96 return res, nil 97 default: 98 continue 99 } 100 case <-w.done: 101 return nil, ErrWatcherStopped 102 } 103 } 104 } 105 106 // Chan returns watcher events channel 107 func (w *tableWatcher) Chan() (<-chan *Event, error) { 108 return w.resChan, nil 109 } 110 111 // Stop stops routing table watcher 112 func (w *tableWatcher) Stop() { 113 w.Lock() 114 defer w.Unlock() 115 116 select { 117 case <-w.done: 118 return 119 default: 120 close(w.done) 121 } 122 }