github.com/Heebron/moby@v0.0.0-20221111184709-6eab4f55faf7/libnetwork/networkdb/broadcast.go (about) 1 package networkdb 2 3 import ( 4 "errors" 5 "time" 6 7 "github.com/hashicorp/memberlist" 8 "github.com/hashicorp/serf/serf" 9 ) 10 11 const broadcastTimeout = 5 * time.Second 12 13 type networkEventMessage struct { 14 id string 15 node string 16 msg []byte 17 } 18 19 func (m *networkEventMessage) Invalidates(other memberlist.Broadcast) bool { 20 otherm := other.(*networkEventMessage) 21 return m.id == otherm.id && m.node == otherm.node 22 } 23 24 func (m *networkEventMessage) Message() []byte { 25 return m.msg 26 } 27 28 func (m *networkEventMessage) Finished() { 29 } 30 31 func (nDB *NetworkDB) sendNetworkEvent(nid string, event NetworkEvent_Type, ltime serf.LamportTime) error { 32 nEvent := NetworkEvent{ 33 Type: event, 34 LTime: ltime, 35 NodeName: nDB.config.NodeID, 36 NetworkID: nid, 37 } 38 39 raw, err := encodeMessage(MessageTypeNetworkEvent, &nEvent) 40 if err != nil { 41 return err 42 } 43 44 nDB.networkBroadcasts.QueueBroadcast(&networkEventMessage{ 45 msg: raw, 46 id: nid, 47 node: nDB.config.NodeID, 48 }) 49 return nil 50 } 51 52 type nodeEventMessage struct { 53 msg []byte 54 notify chan<- struct{} 55 } 56 57 func (m *nodeEventMessage) Invalidates(other memberlist.Broadcast) bool { 58 return false 59 } 60 61 func (m *nodeEventMessage) Message() []byte { 62 return m.msg 63 } 64 65 func (m *nodeEventMessage) Finished() { 66 if m.notify != nil { 67 close(m.notify) 68 } 69 } 70 71 func (nDB *NetworkDB) sendNodeEvent(event NodeEvent_Type) error { 72 nEvent := NodeEvent{ 73 Type: event, 74 LTime: nDB.networkClock.Increment(), 75 NodeName: nDB.config.NodeID, 76 } 77 78 raw, err := encodeMessage(MessageTypeNodeEvent, &nEvent) 79 if err != nil { 80 return err 81 } 82 83 notifyCh := make(chan struct{}) 84 nDB.nodeBroadcasts.QueueBroadcast(&nodeEventMessage{ 85 msg: raw, 86 notify: notifyCh, 87 }) 88 89 nDB.RLock() 90 noPeers := len(nDB.nodes) <= 1 91 nDB.RUnlock() 92 93 // Message enqueued, do not wait for a send if no peer is present 94 if noPeers { 95 return nil 96 } 97 98 // Wait for the broadcast 99 select { 100 case <-notifyCh: 101 case <-time.After(broadcastTimeout): 102 return errors.New("timed out broadcasting node event") 103 } 104 105 return nil 106 } 107 108 type tableEventMessage struct { 109 id string 110 tname string 111 key string 112 msg []byte 113 } 114 115 func (m *tableEventMessage) Invalidates(other memberlist.Broadcast) bool { 116 otherm := other.(*tableEventMessage) 117 return m.tname == otherm.tname && m.id == otherm.id && m.key == otherm.key 118 } 119 120 func (m *tableEventMessage) Message() []byte { 121 return m.msg 122 } 123 124 func (m *tableEventMessage) Finished() { 125 } 126 127 func (nDB *NetworkDB) sendTableEvent(event TableEvent_Type, nid string, tname string, key string, entry *entry) error { 128 tEvent := TableEvent{ 129 Type: event, 130 LTime: entry.ltime, 131 NodeName: nDB.config.NodeID, 132 NetworkID: nid, 133 TableName: tname, 134 Key: key, 135 Value: entry.value, 136 // The duration in second is a float that below would be truncated 137 ResidualReapTime: int32(entry.reapTime.Seconds()), 138 } 139 140 raw, err := encodeMessage(MessageTypeTableEvent, &tEvent) 141 if err != nil { 142 return err 143 } 144 145 var broadcastQ *memberlist.TransmitLimitedQueue 146 nDB.RLock() 147 thisNodeNetworks, ok := nDB.networks[nDB.config.NodeID] 148 if ok { 149 // The network may have been removed 150 network, networkOk := thisNodeNetworks[nid] 151 if !networkOk { 152 nDB.RUnlock() 153 return nil 154 } 155 156 broadcastQ = network.tableBroadcasts 157 } 158 nDB.RUnlock() 159 160 // The network may have been removed 161 if broadcastQ == nil { 162 return nil 163 } 164 165 broadcastQ.QueueBroadcast(&tableEventMessage{ 166 msg: raw, 167 id: nid, 168 tname: tname, 169 key: key, 170 }) 171 return nil 172 }