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  }