Repository: moby/moby
File: libnetwork/networkdb/cluster.go (Go)

Code before:
		nDB.RUnlock()
		if !ok || network == nil {
			// It is normal for the network to be removed
			// between the time we collect the network
			// attachments of this node and processing
			// them here.
			continue
		}

		if network.tableBroadcasts == nil {
			log.G(context.TODO()).Errorf("Invalid broadcastQ encountered while gossiping for network %s", nid)
			continue
		}

		msgs := getBroadcasts(compoundOverhead, bytesAvail, network.tableBroadcasts, network.tableRebroadcasts)
		// Collect stats and print the queue info, note this code is here also to have a view of the queues empty
		network.qMessagesSent.Add(int64(len(msgs)))
		if printStats {
			msent := network.qMessagesSent.Swap(0)
			log.G(context.TODO()).Infof("NetworkDB stats %v(%v) - netID:%s leaving:%t netPeers:%d entries:%d Queue qLen:%d+%d netMsg/s:%d",
				nDB.config.Hostname, nDB.config.NodeID,
				nid, network.leaving, network.tableBroadcasts.NumNodes(), network.entriesNumber.Load(),
				network.tableBroadcasts.NumQueued(), network.tableRebroadcasts.NumQueued(),
				msent/int64((nDB.config.StatsPrintPeriod/time.Second)))
		}

		if len(msgs) == 0 {
			continue
		}

		// Create a compound message
		compound := makeCompoundMessage(msgs)

		for _, node := range mNodes {
			nDB.RLock()
			mnode := nDB.nodes[node]
			nDB.RUnlock()

			if mnode == nil {
				break
			}

			// Send the compound message
			if err := nDB.memberlist.SendBestEffort(&mnode.Node, compound); err != nil {
				log.G(context.TODO()).Errorf("Failed to send gossip to %s: %s", mnode.Addr, err)
			}
		}
	}
	// Reset the stats
	if printStats {
		nDB.lastStatsTimestamp = time.Now()

Review comment (suggestion):
`network.tableBroadcasts` is checked above, but can `network.tableRebroadcasts` be nil here?

JoinNetwork sets up both before adding a `network` to `networkNodes`. So, if one is non-nil, the other is also non-nil? (In which case, worth a comment if not an extra nil check?)

Code after:
	}

	for nid, nodes := range networkNodes {
		mNodes := nDB.mRandomNodes(3, nodes)
		bytesAvail := nDB.config.PacketBufferSize - compoundHeaderOverhead

		nDB.RLock()
		network, ok := nDB.thisNodeNetworks[nid]
		nDB.RUnlock()
		if !ok || network == nil {
			// It is normal for the network to be removed
			// between the time we collect the network
			// attachments of this node and processing
			// them here.
			continue
		}

		msgs := getBroadcasts(compoundOverhead, bytesAvail, network.tableBroadcasts, network.tableRebroadcasts)
		// Collect stats and print the queue info, note this code is here also to have a view of the queues empty
		network.qMessagesSent.Add(int64(len(msgs)))
		if printStats {
			msent := network.qMessagesSent.Swap(0)
			log.G(context.TODO()).Infof("NetworkDB stats %v(%v) - netID:%s leaving:%t netPeers:%d entries:%d Queue qLen:%d+%d netMsg/s:%d",
				nDB.config.Hostname, nDB.config.NodeID,
				nid, network.leaving, network.tableBroadcasts.NumNodes(), network.entriesNumber.Load(),
				network.tableBroadcasts.NumQueued(), network.tableRebroadcasts.NumQueued(),
				msent/int64((nDB.config.StatsPrintPeriod/time.Second)))
		}

		if len(msgs) == 0 {
			continue
		}

		// Create a compound message
		compound := makeCompoundMessage(msgs)

		for _, node := range mNodes {
			nDB.RLock()
			mnode := nDB.nodes[node]
			nDB.RUnlock()

			if mnode == nil {
				break
			}

			// Send the compound message
			if err := nDB.memberlist.SendBestEffort(&mnode.Node, compound); err != nil {
				log.G(context.TODO()).Errorf("Failed to send gossip to %s: %s", mnode.Addr, err)
			}
		}
	}