github.com/zhuohuang-hust/src-cbuild@v0.0.0-20230105071821-c7aab3e7c840/mergeCode/libnetwork/networkdb/delegate.go (about) 1 package networkdb 2 3 import ( 4 "fmt" 5 "net" 6 "strings" 7 "time" 8 9 "github.com/Sirupsen/logrus" 10 "github.com/gogo/protobuf/proto" 11 ) 12 13 type delegate struct { 14 nDB *NetworkDB 15 } 16 17 func (d *delegate) NodeMeta(limit int) []byte { 18 return []byte{} 19 } 20 21 func (nDB *NetworkDB) checkAndGetNode(nEvent *NodeEvent) *node { 22 nDB.Lock() 23 defer nDB.Unlock() 24 25 for _, nodes := range []map[string]*node{ 26 nDB.failedNodes, 27 nDB.leftNodes, 28 nDB.nodes, 29 } { 30 if n, ok := nodes[nEvent.NodeName]; ok { 31 if n.ltime >= nEvent.LTime { 32 return nil 33 } 34 35 delete(nodes, n.Name) 36 return n 37 } 38 } 39 40 return nil 41 } 42 43 func (nDB *NetworkDB) purgeSameNode(n *node) { 44 nDB.Lock() 45 defer nDB.Unlock() 46 47 prefix := strings.Split(n.Name, "-")[0] 48 for _, nodes := range []map[string]*node{ 49 nDB.failedNodes, 50 nDB.leftNodes, 51 nDB.nodes, 52 } { 53 var nodeNames []string 54 for name, node := range nodes { 55 if strings.HasPrefix(name, prefix) && n.Addr.Equal(node.Addr) { 56 nodeNames = append(nodeNames, name) 57 } 58 } 59 60 for _, name := range nodeNames { 61 delete(nodes, name) 62 } 63 } 64 } 65 66 func (nDB *NetworkDB) handleNodeEvent(nEvent *NodeEvent) bool { 67 n := nDB.checkAndGetNode(nEvent) 68 if n == nil { 69 return false 70 } 71 72 nDB.purgeSameNode(n) 73 n.ltime = nEvent.LTime 74 75 switch nEvent.Type { 76 case NodeEventTypeJoin: 77 nDB.Lock() 78 nDB.nodes[n.Name] = n 79 nDB.Unlock() 80 return true 81 case NodeEventTypeLeave: 82 nDB.Lock() 83 nDB.leftNodes[n.Name] = n 84 nDB.Unlock() 85 return true 86 } 87 88 return false 89 } 90 91 func (nDB *NetworkDB) handleNetworkEvent(nEvent *NetworkEvent) bool { 92 // Update our local clock if the received messages has newer 93 // time. 94 nDB.networkClock.Witness(nEvent.LTime) 95 96 nDB.Lock() 97 defer nDB.Unlock() 98 99 if nEvent.NodeName == nDB.config.NodeName { 100 return false 101 } 102 103 nodeNetworks, ok := nDB.networks[nEvent.NodeName] 104 if !ok { 105 // We haven't heard about this node at all. Ignore the leave 106 if nEvent.Type == NetworkEventTypeLeave { 107 return false 108 } 109 110 nodeNetworks = make(map[string]*network) 111 nDB.networks[nEvent.NodeName] = nodeNetworks 112 } 113 114 if n, ok := nodeNetworks[nEvent.NetworkID]; ok { 115 // We have the latest state. Ignore the event 116 // since it is stale. 117 if n.ltime >= nEvent.LTime { 118 return false 119 } 120 121 n.ltime = nEvent.LTime 122 n.leaving = nEvent.Type == NetworkEventTypeLeave 123 if n.leaving { 124 n.leaveTime = time.Now() 125 } 126 127 nDB.addNetworkNode(nEvent.NetworkID, nEvent.NodeName) 128 return true 129 } 130 131 if nEvent.Type == NetworkEventTypeLeave { 132 return false 133 } 134 135 // This remote network join is being seen the first time. 136 nodeNetworks[nEvent.NetworkID] = &network{ 137 id: nEvent.NetworkID, 138 ltime: nEvent.LTime, 139 } 140 141 nDB.addNetworkNode(nEvent.NetworkID, nEvent.NodeName) 142 return true 143 } 144 145 func (nDB *NetworkDB) handleTableEvent(tEvent *TableEvent) bool { 146 // Update our local clock if the received messages has newer 147 // time. 148 nDB.tableClock.Witness(tEvent.LTime) 149 150 // Ignore the table events for networks that are in the process of going away 151 nDB.RLock() 152 networks := nDB.networks[nDB.config.NodeName] 153 network, ok := networks[tEvent.NetworkID] 154 nDB.RUnlock() 155 if !ok || network.leaving { 156 return true 157 } 158 159 e, err := nDB.getEntry(tEvent.TableName, tEvent.NetworkID, tEvent.Key) 160 if err != nil && tEvent.Type == TableEventTypeDelete { 161 // If it is a delete event and we don't have the entry here nothing to do. 162 return false 163 } 164 165 if err == nil { 166 // We have the latest state. Ignore the event 167 // since it is stale. 168 if e.ltime >= tEvent.LTime { 169 return false 170 } 171 } 172 173 e = &entry{ 174 ltime: tEvent.LTime, 175 node: tEvent.NodeName, 176 value: tEvent.Value, 177 deleting: tEvent.Type == TableEventTypeDelete, 178 } 179 180 if e.deleting { 181 e.deleteTime = time.Now() 182 } 183 184 nDB.Lock() 185 nDB.indexes[byTable].Insert(fmt.Sprintf("/%s/%s/%s", tEvent.TableName, tEvent.NetworkID, tEvent.Key), e) 186 nDB.indexes[byNetwork].Insert(fmt.Sprintf("/%s/%s/%s", tEvent.NetworkID, tEvent.TableName, tEvent.Key), e) 187 nDB.Unlock() 188 189 var op opType 190 switch tEvent.Type { 191 case TableEventTypeCreate: 192 op = opCreate 193 case TableEventTypeUpdate: 194 op = opUpdate 195 case TableEventTypeDelete: 196 op = opDelete 197 } 198 199 nDB.broadcaster.Write(makeEvent(op, tEvent.TableName, tEvent.NetworkID, tEvent.Key, tEvent.Value)) 200 return true 201 } 202 203 func (nDB *NetworkDB) handleCompound(buf []byte, isBulkSync bool) { 204 // Decode the parts 205 parts, err := decodeCompoundMessage(buf) 206 if err != nil { 207 logrus.Errorf("Failed to decode compound request: %v", err) 208 return 209 } 210 211 // Handle each message 212 for _, part := range parts { 213 nDB.handleMessage(part, isBulkSync) 214 } 215 } 216 217 func (nDB *NetworkDB) handleTableMessage(buf []byte, isBulkSync bool) { 218 var tEvent TableEvent 219 if err := proto.Unmarshal(buf, &tEvent); err != nil { 220 logrus.Errorf("Error decoding table event message: %v", err) 221 return 222 } 223 224 // Ignore messages that this node generated. 225 if tEvent.NodeName == nDB.config.NodeName { 226 return 227 } 228 229 // Do not rebroadcast a bulk sync 230 if rebroadcast := nDB.handleTableEvent(&tEvent); rebroadcast && !isBulkSync { 231 var err error 232 buf, err = encodeRawMessage(MessageTypeTableEvent, buf) 233 if err != nil { 234 logrus.Errorf("Error marshalling gossip message for network event rebroadcast: %v", err) 235 return 236 } 237 238 nDB.RLock() 239 n, ok := nDB.networks[nDB.config.NodeName][tEvent.NetworkID] 240 nDB.RUnlock() 241 242 if !ok { 243 return 244 } 245 246 broadcastQ := n.tableBroadcasts 247 248 if broadcastQ == nil { 249 return 250 } 251 252 broadcastQ.QueueBroadcast(&tableEventMessage{ 253 msg: buf, 254 id: tEvent.NetworkID, 255 tname: tEvent.TableName, 256 key: tEvent.Key, 257 node: nDB.config.NodeName, 258 }) 259 } 260 } 261 262 func (nDB *NetworkDB) handleNodeMessage(buf []byte) { 263 var nEvent NodeEvent 264 if err := proto.Unmarshal(buf, &nEvent); err != nil { 265 logrus.Errorf("Error decoding node event message: %v", err) 266 return 267 } 268 269 if rebroadcast := nDB.handleNodeEvent(&nEvent); rebroadcast { 270 var err error 271 buf, err = encodeRawMessage(MessageTypeNodeEvent, buf) 272 if err != nil { 273 logrus.Errorf("Error marshalling gossip message for node event rebroadcast: %v", err) 274 return 275 } 276 277 nDB.nodeBroadcasts.QueueBroadcast(&nodeEventMessage{ 278 msg: buf, 279 }) 280 } 281 } 282 283 func (nDB *NetworkDB) handleNetworkMessage(buf []byte) { 284 var nEvent NetworkEvent 285 if err := proto.Unmarshal(buf, &nEvent); err != nil { 286 logrus.Errorf("Error decoding network event message: %v", err) 287 return 288 } 289 290 if rebroadcast := nDB.handleNetworkEvent(&nEvent); rebroadcast { 291 var err error 292 buf, err = encodeRawMessage(MessageTypeNetworkEvent, buf) 293 if err != nil { 294 logrus.Errorf("Error marshalling gossip message for network event rebroadcast: %v", err) 295 return 296 } 297 298 nDB.networkBroadcasts.QueueBroadcast(&networkEventMessage{ 299 msg: buf, 300 id: nEvent.NetworkID, 301 node: nEvent.NodeName, 302 }) 303 } 304 } 305 306 func (nDB *NetworkDB) handleBulkSync(buf []byte) { 307 var bsm BulkSyncMessage 308 if err := proto.Unmarshal(buf, &bsm); err != nil { 309 logrus.Errorf("Error decoding bulk sync message: %v", err) 310 return 311 } 312 313 if bsm.LTime > 0 { 314 nDB.tableClock.Witness(bsm.LTime) 315 } 316 317 nDB.handleMessage(bsm.Payload, true) 318 319 // Don't respond to a bulk sync which was not unsolicited 320 if !bsm.Unsolicited { 321 nDB.Lock() 322 ch, ok := nDB.bulkSyncAckTbl[bsm.NodeName] 323 if ok { 324 close(ch) 325 delete(nDB.bulkSyncAckTbl, bsm.NodeName) 326 } 327 nDB.Unlock() 328 329 return 330 } 331 332 var nodeAddr net.IP 333 nDB.RLock() 334 if node, ok := nDB.nodes[bsm.NodeName]; ok { 335 nodeAddr = node.Addr 336 } 337 nDB.RUnlock() 338 339 if err := nDB.bulkSyncNode(bsm.Networks, bsm.NodeName, false); err != nil { 340 logrus.Errorf("Error in responding to bulk sync from node %s: %v", nodeAddr, err) 341 } 342 } 343 344 func (nDB *NetworkDB) handleMessage(buf []byte, isBulkSync bool) { 345 mType, data, err := decodeMessage(buf) 346 if err != nil { 347 logrus.Errorf("Error decoding gossip message to get message type: %v", err) 348 return 349 } 350 351 switch mType { 352 case MessageTypeNodeEvent: 353 nDB.handleNodeMessage(data) 354 case MessageTypeNetworkEvent: 355 nDB.handleNetworkMessage(data) 356 case MessageTypeTableEvent: 357 nDB.handleTableMessage(data, isBulkSync) 358 case MessageTypeBulkSync: 359 nDB.handleBulkSync(data) 360 case MessageTypeCompound: 361 nDB.handleCompound(data, isBulkSync) 362 default: 363 logrus.Errorf("%s: unknown message type %d", nDB.config.NodeName, mType) 364 } 365 } 366 367 func (d *delegate) NotifyMsg(buf []byte) { 368 if len(buf) == 0 { 369 return 370 } 371 372 d.nDB.handleMessage(buf, false) 373 } 374 375 func (d *delegate) GetBroadcasts(overhead, limit int) [][]byte { 376 msgs := d.nDB.networkBroadcasts.GetBroadcasts(overhead, limit) 377 msgs = append(msgs, d.nDB.nodeBroadcasts.GetBroadcasts(overhead, limit)...) 378 return msgs 379 } 380 381 func (d *delegate) LocalState(join bool) []byte { 382 if join { 383 // Update all the local node/network state to a new time to 384 // force update on the node we are trying to rejoin, just in 385 // case that node has these in leaving state still. This is 386 // facilitate fast convergence after recovering from a gossip 387 // failure. 388 d.nDB.updateLocalNetworkTime() 389 } 390 391 d.nDB.RLock() 392 defer d.nDB.RUnlock() 393 394 pp := NetworkPushPull{ 395 LTime: d.nDB.networkClock.Time(), 396 NodeName: d.nDB.config.NodeName, 397 } 398 399 for name, nn := range d.nDB.networks { 400 for _, n := range nn { 401 pp.Networks = append(pp.Networks, &NetworkEntry{ 402 LTime: n.ltime, 403 NetworkID: n.id, 404 NodeName: name, 405 Leaving: n.leaving, 406 }) 407 } 408 } 409 410 buf, err := encodeMessage(MessageTypePushPull, &pp) 411 if err != nil { 412 logrus.Errorf("Failed to encode local network state: %v", err) 413 return nil 414 } 415 416 return buf 417 } 418 419 func (d *delegate) MergeRemoteState(buf []byte, isJoin bool) { 420 if len(buf) == 0 { 421 logrus.Error("zero byte remote network state received") 422 return 423 } 424 425 var gMsg GossipMessage 426 err := proto.Unmarshal(buf, &gMsg) 427 if err != nil { 428 logrus.Errorf("Error unmarshalling push pull messsage: %v", err) 429 return 430 } 431 432 if gMsg.Type != MessageTypePushPull { 433 logrus.Errorf("Invalid message type %v received from remote", buf[0]) 434 } 435 436 pp := NetworkPushPull{} 437 if err := proto.Unmarshal(gMsg.Data, &pp); err != nil { 438 logrus.Errorf("Failed to decode remote network state: %v", err) 439 return 440 } 441 442 nodeEvent := &NodeEvent{ 443 LTime: pp.LTime, 444 NodeName: pp.NodeName, 445 Type: NodeEventTypeJoin, 446 } 447 d.nDB.handleNodeEvent(nodeEvent) 448 449 for _, n := range pp.Networks { 450 nEvent := &NetworkEvent{ 451 LTime: n.LTime, 452 NodeName: n.NodeName, 453 NetworkID: n.NetworkID, 454 Type: NetworkEventTypeJoin, 455 } 456 457 if n.Leaving { 458 nEvent.Type = NetworkEventTypeLeave 459 } 460 461 d.nDB.handleNetworkEvent(nEvent) 462 } 463 464 }