| package networkdb |
| |
| import ( |
| "net" |
| |
| "github.com/docker/go-events" |
| ) |
| |
| type opType uint8 |
| |
| const ( |
| opCreate opType = 1 + iota |
| opUpdate |
| opDelete |
| ) |
| |
| type event struct { |
| Table string |
| NetworkID string |
| Key string |
| Value []byte |
| } |
| |
| // NodeTable represents table event for node join and leave |
| const NodeTable = "NodeTable" |
| |
| // NodeAddr represents the value carried for node event in NodeTable |
| type NodeAddr struct { |
| Addr net.IP |
| } |
| |
| // CreateEvent generates a table entry create event to the watchers |
| type CreateEvent event |
| |
| // UpdateEvent generates a table entry update event to the watchers |
| type UpdateEvent event |
| |
| // DeleteEvent generates a table entry delete event to the watchers |
| type DeleteEvent event |
| |
| // Watch creates a watcher with filters for a particular table or |
| // network or key or any combination of the tuple. If any of the |
| // filter is an empty string it acts as a wildcard for that |
| // field. Watch returns a channel of events, where the events will be |
| // sent. |
| func (nDB *NetworkDB) Watch(tname, nid, key string) (*events.Channel, func()) { |
| var matcher events.Matcher |
| |
| if tname != "" || nid != "" || key != "" { |
| matcher = events.MatcherFunc(func(ev events.Event) bool { |
| var evt event |
| switch ev := ev.(type) { |
| case CreateEvent: |
| evt = event(ev) |
| case UpdateEvent: |
| evt = event(ev) |
| case DeleteEvent: |
| evt = event(ev) |
| } |
| |
| if tname != "" && evt.Table != tname { |
| return false |
| } |
| |
| if nid != "" && evt.NetworkID != nid { |
| return false |
| } |
| |
| if key != "" && evt.Key != key { |
| return false |
| } |
| |
| return true |
| }) |
| } |
| |
| ch := events.NewChannel(0) |
| sink := events.Sink(events.NewQueue(ch)) |
| |
| if matcher != nil { |
| sink = events.NewFilter(sink, matcher) |
| } |
| |
| nDB.broadcaster.Add(sink) |
| return ch, func() { |
| nDB.broadcaster.Remove(sink) |
| ch.Close() |
| sink.Close() |
| } |
| } |
| |
| func makeEvent(op opType, tname, nid, key string, value []byte) events.Event { |
| ev := event{ |
| Table: tname, |
| NetworkID: nid, |
| Key: key, |
| Value: value, |
| } |
| |
| switch op { |
| case opCreate: |
| return CreateEvent(ev) |
| case opUpdate: |
| return UpdateEvent(ev) |
| case opDelete: |
| return DeleteEvent(ev) |
| } |
| |
| return nil |
| } |