github.com/geniusesgroup/libgo@v0.0.0-20220713101832-828057a9d3d4/achaemenid/nodes.go (about)

     1  /* For license and copyright information please see LEGAL file in repository */
     2  
     3  package achaemenid
     4  
     5  import (
     6  	"bytes"
     7  	"context"
     8  	"net"
     9  
    10  	"../log"
    11  	"../uuid"
    12  )
    13  
    14  type nodes struct {
    15  	LocalNode    *Node
    16  	Nodes        []Node // sort in nodeID
    17  	nodesDetails []NodeDetails
    18  }
    19  
    20  // Init use to get other node data and make connection to each of them
    21  func (n *nodes) Init() (err protocol.Error) {
    22  	var goErr error
    23  
    24  	var localNode = Node{
    25  		InstanceID: uuid.Random32Byte(),
    26  		State:      NodeStateLocalNode,
    27  	}
    28  
    29  	if protocol.AppDevMode {
    30  		n.LocalNode = &localNode
    31  		n.Nodes = append(n.Nodes, localNode)
    32  	} else {
    33  		// TODO::: change to Giti network when it is ready to serve lookup domain to GP address.
    34  		var ipsAddr []net.IPAddr
    35  		ipsAddr, goErr = net.DefaultResolver.LookupIPAddr(context.Background(), Server.Manifest.DomainName)
    36  		if goErr != nil {
    37  			// TODO::: block and try agin for 3 times??
    38  		}
    39  
    40  		if protocol.AppDebugMode {
    41  			log.Debug("Achaemenid - Available nodes addr:", ipsAddr)
    42  		}
    43  
    44  		// Check if this is first instance of platform app.
    45  		if len(ipsAddr) == 1 {
    46  			n.Nodes = append(n.Nodes, localNode)
    47  			n.LocalNode = &n.Nodes[0]
    48  		} else {
    49  			var conn *Connection
    50  			var ipAddr [16]byte
    51  			copy(ipAddr[:], ipsAddr[0].IP)
    52  			conn, err = Server.Connections.MakeNewIPConnection(ipAddr)
    53  			if err != nil {
    54  				// TODO::: why fresh starting app can't make new connection???
    55  			}
    56  			var res *getServerNodeDetailsRes
    57  			res, err = getServerNodeDetails(conn)
    58  			if err != nil {
    59  				// TODO::: try other node to get platform nodes??
    60  			}
    61  
    62  			var ln = len(res.nodes)
    63  			n.Nodes = make([]Node, ln)
    64  			n.nodesDetails = make([]NodeDetails, ln)
    65  			for i := 0; i < ln; i++ {
    66  				n.Nodes[i].ID = res.nodes[i].ID
    67  				n.nodesDetails[i].ID = res.nodes[i].ID
    68  
    69  				n.nodesDetails[i].GPAddr = res.nodes[i].GPAddr
    70  				n.nodesDetails[i].IPAddr = res.nodes[i].IPAddr
    71  
    72  				if !bytes.Equal(res.nodes[i].IPAddr[:], Server.Networks.localIP[:]) {
    73  					n.Nodes[i].Conn, err = Server.Connections.MakeNewIPConnection(res.nodes[i].IPAddr)
    74  				}
    75  			}
    76  		}
    77  
    78  		// Register local node to cluster
    79  	}
    80  	return
    81  }
    82  
    83  // GetServerNodeDetails returns all platform nodes details.
    84  func (n *nodes) GetServerNodeDetails() (nd []NodeDetails) {
    85  	return n.nodesDetails
    86  }
    87  
    88  type getServerNodeDetailsRes struct {
    89  	nodes []NodeDetails
    90  }
    91  
    92  func getServerNodeDetails(conn *Connection) (res *getServerNodeDetailsRes, err protocol.Error) {
    93  	// Make new request-response streams
    94  	var st *Stream
    95  	st, err = conn.MakeOutcomeStream(0)
    96  	if err != nil {
    97  		return
    98  	}
    99  
   100  	// Set GetServerNodes ServiceID
   101  	st.Service = &Service{ID: 639492616}
   102  
   103  	err = SrpcOutcomeRequestHandler(st)
   104  	if err != nil {
   105  		return
   106  	}
   107  
   108  	err = res.FromSyllab(st.OutcomePayload)
   109  	return
   110  }
   111  
   112  func (res *getServerNodeDetailsRes) FromSyllab(buf []byte) protocol.Error {
   113  	// TODO:::
   114  	return nil
   115  }
   116  
   117  // GetNodeByID returns exiting node.
   118  func (n *nodes) GetNodeByID(nodeID uint64) *Node {
   119  	return &n.Nodes[nodeID]
   120  }