github.com/Heebron/moby@v0.0.0-20221111184709-6eab4f55faf7/libnetwork/networkdb/watch.go (about) 1 package networkdb 2 3 import ( 4 "net" 5 6 "github.com/docker/go-events" 7 ) 8 9 type opType uint8 10 11 const ( 12 opCreate opType = 1 + iota 13 opUpdate 14 opDelete 15 ) 16 17 type event struct { 18 Table string 19 NetworkID string 20 Key string 21 Value []byte 22 } 23 24 // NodeTable represents table event for node join and leave 25 const NodeTable = "NodeTable" 26 27 // NodeAddr represents the value carried for node event in NodeTable 28 type NodeAddr struct { 29 Addr net.IP 30 } 31 32 // CreateEvent generates a table entry create event to the watchers 33 type CreateEvent event 34 35 // UpdateEvent generates a table entry update event to the watchers 36 type UpdateEvent event 37 38 // DeleteEvent generates a table entry delete event to the watchers 39 type DeleteEvent event 40 41 // Watch creates a watcher with filters for a particular table or 42 // network or key or any combination of the tuple. If any of the 43 // filter is an empty string it acts as a wildcard for that 44 // field. Watch returns a channel of events, where the events will be 45 // sent. 46 func (nDB *NetworkDB) Watch(tname, nid, key string) (*events.Channel, func()) { 47 var matcher events.Matcher 48 49 if tname != "" || nid != "" || key != "" { 50 matcher = events.MatcherFunc(func(ev events.Event) bool { 51 var evt event 52 switch ev := ev.(type) { 53 case CreateEvent: 54 evt = event(ev) 55 case UpdateEvent: 56 evt = event(ev) 57 case DeleteEvent: 58 evt = event(ev) 59 } 60 61 if tname != "" && evt.Table != tname { 62 return false 63 } 64 65 if nid != "" && evt.NetworkID != nid { 66 return false 67 } 68 69 if key != "" && evt.Key != key { 70 return false 71 } 72 73 return true 74 }) 75 } 76 77 ch := events.NewChannel(0) 78 sink := events.Sink(events.NewQueue(ch)) 79 80 if matcher != nil { 81 sink = events.NewFilter(sink, matcher) 82 } 83 84 nDB.broadcaster.Add(sink) 85 return ch, func() { 86 nDB.broadcaster.Remove(sink) 87 ch.Close() 88 sink.Close() 89 } 90 } 91 92 func makeEvent(op opType, tname, nid, key string, value []byte) events.Event { 93 ev := event{ 94 Table: tname, 95 NetworkID: nid, 96 Key: key, 97 Value: value, 98 } 99 100 switch op { 101 case opCreate: 102 return CreateEvent(ev) 103 case opUpdate: 104 return UpdateEvent(ev) 105 case opDelete: 106 return DeleteEvent(ev) 107 } 108 109 return nil 110 }