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>
127 lines
2.4 KiB
Go
127 lines
2.4 KiB
Go
package networkdb
|
|
|
|
import (
|
|
"github.com/hashicorp/memberlist"
|
|
"github.com/hashicorp/serf/serf"
|
|
)
|
|
|
|
type networkEventType uint8
|
|
|
|
const (
|
|
networkJoin networkEventType = 1 + iota
|
|
networkLeave
|
|
)
|
|
|
|
type networkEventData struct {
|
|
Event networkEventType
|
|
LTime serf.LamportTime
|
|
NodeName string
|
|
NetworkID string
|
|
}
|
|
|
|
type networkEventMessage struct {
|
|
id string
|
|
node string
|
|
msg []byte
|
|
}
|
|
|
|
func (m *networkEventMessage) Invalidates(other memberlist.Broadcast) bool {
|
|
otherm := other.(*networkEventMessage)
|
|
return m.id == otherm.id && m.node == otherm.node
|
|
}
|
|
|
|
func (m *networkEventMessage) Message() []byte {
|
|
return m.msg
|
|
}
|
|
|
|
func (m *networkEventMessage) Finished() {
|
|
}
|
|
|
|
func (nDB *NetworkDB) sendNetworkEvent(nid string, event networkEventType, ltime serf.LamportTime) error {
|
|
nEvent := networkEventData{
|
|
Event: event,
|
|
LTime: ltime,
|
|
NodeName: nDB.config.NodeName,
|
|
NetworkID: nid,
|
|
}
|
|
|
|
raw, err := encodeMessage(networkEventMsg, &nEvent)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
nDB.networkBroadcasts.QueueBroadcast(&networkEventMessage{
|
|
msg: raw,
|
|
id: nid,
|
|
node: nDB.config.NodeName,
|
|
})
|
|
return nil
|
|
}
|
|
|
|
type tableEventType uint8
|
|
|
|
const (
|
|
tableEntryCreate tableEventType = 1 + iota
|
|
tableEntryUpdate
|
|
tableEntryDelete
|
|
)
|
|
|
|
type tableEventData struct {
|
|
Event tableEventType
|
|
LTime serf.LamportTime
|
|
NetworkID string
|
|
TableName string
|
|
NodeName string
|
|
Value []byte
|
|
Key string
|
|
}
|
|
|
|
type tableEventMessage struct {
|
|
id string
|
|
tname string
|
|
key string
|
|
msg []byte
|
|
node string
|
|
}
|
|
|
|
func (m *tableEventMessage) Invalidates(other memberlist.Broadcast) bool {
|
|
otherm := other.(*tableEventMessage)
|
|
return m.id == otherm.id && m.tname == otherm.tname && m.key == otherm.key
|
|
}
|
|
|
|
func (m *tableEventMessage) Message() []byte {
|
|
return m.msg
|
|
}
|
|
|
|
func (m *tableEventMessage) Finished() {
|
|
}
|
|
|
|
func (nDB *NetworkDB) sendTableEvent(event tableEventType, nid string, tname string, key string, entry *entry) error {
|
|
tEvent := tableEventData{
|
|
Event: event,
|
|
LTime: entry.ltime,
|
|
NodeName: nDB.config.NodeName,
|
|
NetworkID: nid,
|
|
TableName: tname,
|
|
Key: key,
|
|
Value: entry.value,
|
|
}
|
|
|
|
raw, err := encodeMessage(tableEventMsg, &tEvent)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
nDB.RLock()
|
|
broadcastQ := nDB.networks[nDB.config.NodeName][nid].tableBroadcasts
|
|
nDB.RUnlock()
|
|
|
|
broadcastQ.QueueBroadcast(&tableEventMessage{
|
|
msg: raw,
|
|
id: nid,
|
|
tname: tname,
|
|
key: key,
|
|
node: nDB.config.NodeName,
|
|
})
|
|
return nil
|
|
}
|