github.com/zhuohuang-hust/src-cbuild@v0.0.0-20230105071821-c7aab3e7c840/mergeCode/libnetwork/networkdb/broadcast.go (about)

     1  package networkdb
     2  
     3  import (
     4  	"fmt"
     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.NodeName,
    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.NodeName,
    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.NodeName,
    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  	// Wait for the broadcast
    90  	select {
    91  	case <-notifyCh:
    92  	case <-time.After(broadcastTimeout):
    93  		return fmt.Errorf("timed out broadcasting node event")
    94  	}
    95  
    96  	return nil
    97  }
    98  
    99  type tableEventMessage struct {
   100  	id    string
   101  	tname string
   102  	key   string
   103  	msg   []byte
   104  	node  string
   105  }
   106  
   107  func (m *tableEventMessage) Invalidates(other memberlist.Broadcast) bool {
   108  	otherm := other.(*tableEventMessage)
   109  	return m.id == otherm.id && m.tname == otherm.tname && m.key == otherm.key
   110  }
   111  
   112  func (m *tableEventMessage) Message() []byte {
   113  	return m.msg
   114  }
   115  
   116  func (m *tableEventMessage) Finished() {
   117  }
   118  
   119  func (nDB *NetworkDB) sendTableEvent(event TableEvent_Type, nid string, tname string, key string, entry *entry) error {
   120  	tEvent := TableEvent{
   121  		Type:      event,
   122  		LTime:     entry.ltime,
   123  		NodeName:  nDB.config.NodeName,
   124  		NetworkID: nid,
   125  		TableName: tname,
   126  		Key:       key,
   127  		Value:     entry.value,
   128  	}
   129  
   130  	raw, err := encodeMessage(MessageTypeTableEvent, &tEvent)
   131  	if err != nil {
   132  		return err
   133  	}
   134  
   135  	var broadcastQ *memberlist.TransmitLimitedQueue
   136  	nDB.RLock()
   137  	thisNodeNetworks, ok := nDB.networks[nDB.config.NodeName]
   138  	if ok {
   139  		// The network may have been removed
   140  		network, networkOk := thisNodeNetworks[nid]
   141  		if !networkOk {
   142  			nDB.RUnlock()
   143  			return nil
   144  		}
   145  
   146  		broadcastQ = network.tableBroadcasts
   147  	}
   148  	nDB.RUnlock()
   149  
   150  	// The network may have been removed
   151  	if broadcastQ == nil {
   152  		return nil
   153  	}
   154  
   155  	broadcastQ.QueueBroadcast(&tableEventMessage{
   156  		msg:   raw,
   157  		id:    nid,
   158  		tname: tname,
   159  		key:   key,
   160  		node:  nDB.config.NodeName,
   161  	})
   162  	return nil
   163  }