github.com/ronaksoft/rony@v0.16.26-0.20230807065236-1743dbfe6959/internal/cluster/gossip/member.go (about)

     1  package gossipCluster
     2  
     3  import (
     4  	"net"
     5  
     6  	"github.com/ronaksoft/memberlist"
     7  	"github.com/ronaksoft/rony"
     8  	"github.com/ronaksoft/rony/errors"
     9  	"github.com/ronaksoft/rony/internal/msg"
    10  	"google.golang.org/protobuf/proto"
    11  )
    12  
    13  /*
    14     Creation Time: 2021 - Jan - 14
    15     Created by:  (ehsan)
    16     Maintainers:
    17        1.  Ehsan N. Moosa (E2)
    18     Auditor: Ehsan N. Moosa (E2)
    19     Copyright Ronak Software Group 2020
    20  */
    21  
    22  type Member struct {
    23  	idx         int
    24  	serverID    string
    25  	replicaSet  uint64
    26  	hash        uint64
    27  	gatewayAddr []string
    28  	tunnelAddr  []string
    29  	ClusterAddr net.IP
    30  	ClusterPort uint16
    31  }
    32  
    33  func (m *Member) ServerID() string {
    34  	return m.serverID
    35  }
    36  
    37  func (m *Member) ReplicaSet() uint64 {
    38  	return m.replicaSet
    39  }
    40  
    41  func (m *Member) GatewayAddr() []string {
    42  	return m.gatewayAddr
    43  }
    44  
    45  func (m *Member) TunnelAddr() []string {
    46  	return m.tunnelAddr
    47  }
    48  
    49  func (m *Member) Proto(p *rony.Edge) *rony.Edge {
    50  	if p == nil {
    51  		p = &rony.Edge{}
    52  	}
    53  	p.ReplicaSet = m.replicaSet
    54  	p.ServerID = m.serverID
    55  	p.HostPorts = append(p.HostPorts, m.gatewayAddr...)
    56  
    57  	return p
    58  }
    59  
    60  func (m *Member) Merge(en *msg.EdgeNode) {
    61  	m.replicaSet = en.GetReplicaSet()
    62  	m.gatewayAddr = append(m.gatewayAddr[:0], en.GetGatewayAddr()...)
    63  	m.tunnelAddr = append(m.tunnelAddr[:0], en.GetTunnelAddr()...)
    64  }
    65  
    66  func (m *Member) Dial() (net.Conn, error) {
    67  	if len(m.tunnelAddr) == 0 {
    68  		return nil, errors.ErrNoTunnelAddrs
    69  	}
    70  
    71  	idx := m.idx
    72  	for {
    73  		conn, err := net.Dial("udp", m.tunnelAddr[idx])
    74  		if err == nil {
    75  			m.idx = idx
    76  
    77  			return conn, nil
    78  		}
    79  		idx = (idx + 1) % len(m.tunnelAddr)
    80  		if idx == m.idx {
    81  			return nil, err
    82  		}
    83  	}
    84  }
    85  
    86  func newMember(sm *memberlist.Node) (*Member, error) {
    87  	en := msg.PoolEdgeNode.Get()
    88  	defer msg.PoolEdgeNode.Put(en)
    89  
    90  	if err := extractNode(sm, en); err != nil {
    91  		return nil, err
    92  	}
    93  
    94  	m := &Member{
    95  		serverID:    string(en.ServerID),
    96  		hash:        en.Hash,
    97  		ClusterAddr: sm.Addr,
    98  		ClusterPort: sm.Port,
    99  	}
   100  	m.Merge(en)
   101  
   102  	return m, nil
   103  }
   104  
   105  func extractNode(n *memberlist.Node, en *msg.EdgeNode) error {
   106  	return proto.UnmarshalOptions{}.Unmarshal(n.Meta, en)
   107  }