1package networkdb 2 3import ( 4 "net" 5 6 "github.com/docker/go-events" 7) 8 9type opType uint8 10 11const ( 12 opCreate opType = 1 + iota 13 opUpdate 14 opDelete 15) 16 17type 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 25const NodeTable = "NodeTable" 26 27// NodeAddr represents the value carried for node event in NodeTable 28type NodeAddr struct { 29 Addr net.IP 30} 31 32// CreateEvent generates a table entry create event to the watchers 33type CreateEvent event 34 35// UpdateEvent generates a table entry update event to the watchers 36type UpdateEvent event 37 38// DeleteEvent generates a table entry delete event to the watchers 39type 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. 46func (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 92func 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} 111