github.com/zhyoulun/cilium@v1.6.12/pkg/kvstore/events.go (about) 1 // Copyright 2016-2018 Authors of Cilium 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package kvstore 16 17 import ( 18 "sync" 19 ) 20 21 // EventType defines the type of watch event that occurred 22 type EventType int 23 24 const ( 25 // EventTypeCreate represents a newly created key 26 EventTypeCreate EventType = iota 27 // EventTypeModify represents a modified key 28 EventTypeModify 29 // EventTypeDelete represents a deleted key 30 EventTypeDelete 31 //EventTypeListDone signals that the initial list operation has completed 32 EventTypeListDone 33 ) 34 35 // String() returns the human readable format of an event type 36 func (t EventType) String() string { 37 switch t { 38 case EventTypeCreate: 39 return "create" 40 case EventTypeModify: 41 return "modify" 42 case EventTypeDelete: 43 return "delete" 44 case EventTypeListDone: 45 return "listDone" 46 default: 47 return "unknown" 48 } 49 } 50 51 // KeyValueEvent is a change event for a Key/Value pair 52 type KeyValueEvent struct { 53 // Typ is the type of event { EventTypeCreate | EventTypeModify | EventTypeDelete | EventTypeListDone } 54 Typ EventType 55 56 // Key is the kvstore key that changed 57 Key string 58 59 // Value is the kvstore value associated with the key 60 Value []byte 61 } 62 63 // EventChan is a channel to receive events on 64 type EventChan chan KeyValueEvent 65 66 // stopChan is the channel used to indicate stopping of the watcher 67 type stopChan chan struct{} 68 69 // Watcher represents a KVstore watcher 70 type Watcher struct { 71 // Events is the channel to which change notifications will be sent to 72 Events EventChan 73 74 name string 75 prefix string 76 stopWatch stopChan 77 78 // stopOnce guarantees that Stop() is only called once 79 stopOnce sync.Once 80 81 // stopWait is the wait group to wait for watchers to exit gracefully 82 stopWait sync.WaitGroup 83 } 84 85 func newWatcher(name, prefix string, chanSize int) *Watcher { 86 w := &Watcher{ 87 name: name, 88 prefix: prefix, 89 Events: make(EventChan, chanSize), 90 stopWatch: make(stopChan), 91 } 92 93 w.stopWait.Add(1) 94 95 return w 96 } 97 98 // String returns the name of the wather 99 func (w *Watcher) String() string { 100 return w.name 101 } 102 103 // ListAndWatch creates a new watcher which will watch the specified prefix for 104 // changes. Before doing this, it will list the current keys matching the 105 // prefix and report them as new keys. Name can be set to anything and is used 106 // for logging messages. The Events channel is created with the specified 107 // sizes. Upon every change observed, a KeyValueEvent will be sent to the 108 // Events channel 109 // 110 // Returns a watcher structure plus a channel that is closed when the initial 111 // list operation has been completed 112 func ListAndWatch(name, prefix string, chanSize int) *Watcher { 113 return Client().ListAndWatch(name, prefix, chanSize) 114 } 115 116 // Stop stops a watcher previously created and started with Watch() 117 func (w *Watcher) Stop() { 118 w.stopOnce.Do(func() { 119 close(w.stopWatch) 120 log.WithField(fieldWatcher, w).Debug("Stopped watcher") 121 w.stopWait.Wait() 122 }) 123 }