mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
28f4561e3f
Network DB is a network scoped gossip database built on top of hashicorp/memberlist providing an eventually consistent state store. It limits the scope of the gossip and periodic bulk syncing for table entries to only the nodes which participate in the network to which the gossip belongs. This designs make the gossip layer scale better and only consumes resources for the network state that the node participates in. Since the complete state for a network is maintained by all nodes participating in the network, all nodes will eventually converge to the same state. NetworkDB also provides facilities for the users of the package to watch on any table (or all tables) and get notified if there are state changes of interest that happened anywhere in the cluster when that state change eventually finds it's way to the watcher's node. Signed-off-by: Jana Radhakrishnan <mrjana@docker.com>
98 lines
1.9 KiB
Go
98 lines
1.9 KiB
Go
package networkdb
|
|
|
|
import "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
|
|
}
|
|
|
|
// 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) (chan events.Event, 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.C, 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
|
|
}
|