예제 #1
0
 private static void RegisterCluster(string[] args)
 {
     if (args == null)
     {
         return;
     }
     if (args.Length >= 0 && !string.IsNullOrEmpty(args[0]))
     {
         var switches = args[0].Split(new Char[] { '-' }, StringSplitOptions.RemoveEmptyEntries);
         foreach (var optionSwitch in switches)
         {
             var switchValues = optionSwitch.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
             if (switchValues[0].Equals("Nodes"))
             {
                 Logger.Log("INFO :: Discovering the nodes in the cluster.");
                 var nodes = switchValues[1].Replace("'", "").Split(new Char[] { ',' });
                 foreach (var node in nodes)
                 {
                     var       ipParts    = node.Split(new Char[] { '.' }, StringSplitOptions.RemoveEmptyEntries);
                     byte[]    ipPartsArr = ipParts.Select(s => Convert.ToByte(s, 10)).ToArray();
                     IPAddress ip         = new IPAddress(ipPartsArr);
                     NodeRegistryCache.GetInstance().Register(new DummyFollowerNode(ip));
                 }
             }
             else if (switchValues[1].ToUpper().Equals("HELP"))
             {
                 ShowHelp();
             }
         }
     }
 }
        public static void WaitForStartupMessageFromFollowerAsync()
        {
            byte[]     incomingData            = new byte[1024];
            IPEndPoint startupFollowerEndPoint = new IPEndPoint(NodeRegistryCache.GetInstance().IP, STARTUP_PORT_NUMBER);
            Socket     startupFollowerListener = new Socket(startupFollowerEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);

            try
            {
                startupFollowerListener.Bind(startupFollowerEndPoint);
                Logger.Log("INFO :: Node started Listening on port " + STARTUP_PORT_NUMBER + " for new joining followers.");
                startupFollowerListener.Listen(1000);

                while (true)
                {
                    startupAsyncHandler.Reset();
                    startupFollowerListener.BeginAccept(StartupFollowerAcceptCallback, startupFollowerListener);
                    followerPortSwitch.Set();
                    startupAsyncHandler.WaitOne();
                }
            }
            catch (Exception exp)
            {
                Logger.Log(exp.Message);
                followerPortSwitch.Set();
            }
        }
        private static void WaitForHeartbeatMessageFromLeaderAsync()
        {
            byte[] incomingData = new byte[1024];
            byte[] outGoingData = new byte[1024];

            IPEndPoint endPoint = new IPEndPoint(NodeRegistryCache.GetInstance().IP, HEARTBEAT_PORT_NUMBER);

            Socket socketListener = new Socket(endPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);

            try
            {
                socketListener.Bind(endPoint);
                Logger.Log("INFO :: Node started Listening for heartbeat signals on port " + HEARTBEAT_PORT_NUMBER + " .");
                socketListener.Listen(1000);

                while (true)
                {
                    heartbeatAsyncHandler.Reset();
                    socketListener.BeginAccept(HeartbeatAcceptCallback, socketListener);
                    heartBeatPortSwitch.Set();
                    heartbeatAsyncHandler.WaitOne();
                }
            }
            catch (Exception exp)
            {
                Logger.Log(exp.Message);
                heartBeatPortSwitch.Set();
            }
        }
        public static void StartupFollowerReadCallback(IAsyncResult ar)
        {
            String      content = String.Empty;
            StateObject state   = (StateObject)ar.AsyncState;
            Socket      handler = state.workSocket;

            // Read data from the client socket.
            int bytesRead = handler.EndReceive(ar);

            if (bytesRead > 0)
            {
                // There  might be more data, so store the data received so far.
                state.sb.Append(Encoding.ASCII.GetString(
                                    state.buffer, 0, bytesRead));

                // Check for end-of-file tag. If it is not there, read
                // more data.
                content = state.sb.ToString();
                if (content.IndexOf("<EOF>") > -1)
                {
                    var ipAddressArr = content.Split(new String[] { "##" }, StringSplitOptions.RemoveEmptyEntries);
                    if (ipAddressArr != null && ipAddressArr.Count() >= 1)
                    {
                        var               ipParts    = ipAddressArr[0].Split(new Char[] { '.' }, StringSplitOptions.RemoveEmptyEntries);
                        byte[]            ipPartsArr = ipParts.Select(s => Convert.ToByte(s, 10)).ToArray();
                        IPAddress         ip         = new IPAddress(ipPartsArr);
                        DummyFollowerNode node       = new DummyFollowerNode(ip);
                        NodeRegistryCache.GetInstance().Register(node);
                        Logger.Log("New node " + node.ToString() + " successfully added in the cluster.");

                        // send term as the output
                        string responseMsg = NodeRegistryCache.GetInstance().CurrentNode.GetNodeId() + "##"
                                             + NodeRegistryCache.GetInstance().CurrentNode.GetTerm() + "##<EOF>";

                        SendStartupMessageResponse(handler, responseMsg);
                    }
                    else
                    {
                        Logger.Log("Wrong message content on startup follower notification message.");
                    }
                    // Echo the data back to the client.
                }
                else
                {
                    // Not all data received. Get more.
                    handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
                                         new AsyncCallback(StartupFollowerReadCallback), state);
                }
            }
        }
        private static void CandidateRVResponseReadCallback(IAsyncResult ar)
        {
            String      content = String.Empty;
            StateObject state   = (StateObject)ar.AsyncState;
            Socket      handler = state.workSocket;

            // Read data from the client socket.
            int bytesRead = handler.EndReceive(ar);

            if (bytesRead > 0)
            {
                // There  might be more data, so store the data received so far.
                state.sb.Append(Encoding.ASCII.GetString(
                                    state.buffer, 0, bytesRead));

                content = state.sb.ToString();
                if (content.IndexOf("<EOF>") > -1)
                {
                    Logger.Log("INFO :: REQUEST VOTE RPC Response (REC'D).");
                    Candidate candidate = (NodeRegistryCache.GetInstance().CurrentNode as Candidate);
                    if (candidate != null)
                    {
                        candidate.ResponseCallbackFromFollower(content);
                    }
                    else if (NodeRegistryCache.GetInstance().CurrentNode is Leader)
                    {
                        Logger.Log("INFO (L) :: Late RV response received.");
                    }
                    else
                    {
                        Logger.Log("INFO (F) :: Late RV response received. Aleady demoted to follower.");
                    }
                }
                else
                {
                    // Not all data received. Get more.
                    handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
                                         new AsyncCallback(CandidateRVResponseReadCallback), state);
                }
            }
        }
        public static void CandidateReadCallback(IAsyncResult ar)
        {
            String      content = String.Empty;
            StateObject state   = (StateObject)ar.AsyncState;
            Socket      handler = state.workSocket;

            // Read data from the client socket.
            int bytesRead = handler.EndReceive(ar);

            if (bytesRead > 0)
            {
                // There  might be more data, so store the data received so far.
                state.sb.Append(Encoding.ASCII.GetString(
                                    state.buffer, 0, bytesRead));

                // Check for end-of-file tag. If it is not there, read
                // more data.
                content = state.sb.ToString();
                if (content.IndexOf("<EOF>") > -1)
                {
                    // All the data has been read from the
                    // client. Display it on the console.
                    Candidate candidate = (NodeRegistryCache.GetInstance().CurrentNode as Candidate);
                    if (candidate != null)
                    {
                        candidate.ResponseCallbackFromFollower(content);
                    }
                    else
                    {
                        // TO DO . exception response should be passed to candidate node. Log exception
                    }
                }
                else
                {
                    // Not all data received. Get more.
                    handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
                                         new AsyncCallback(CandidateReadCallback), state);
                }
            }
        }
        private static void WaitForRequestVoteRPCAsync()
        {
            IPEndPoint followerLisRequestEndPoint    = new IPEndPoint(NodeRegistryCache.GetInstance().IP, FOLLOWER_PORT_NUMBER);
            Socket     followerRequestListenerSocket = new Socket(followerLisRequestEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);

            try
            {
                followerRequestListenerSocket.Bind(followerLisRequestEndPoint);
                Logger.Log("INFO :: Follower started Listening for REQUEST VOTE RPC on port " + FOLLOWER_PORT_NUMBER + " .");
                followerRequestListenerSocket.Listen(1000);
                while (true)
                {
                    followerAsyncHandler.Reset();
                    followerRequestListenerSocket.BeginAccept(FollowerRVRequestListenerAcceptCallback, followerRequestListenerSocket);
                    candidatePortSwitch.Set();
                    followerAsyncHandler.WaitOne();
                }
            }
            catch (Exception exp)
            {
                Logger.Log(exp.Message);
            }
        }
예제 #8
0
        private static void Setup(String[] args)
        {
            Logger.Log("INFO :: Follower setup process started.");
            string   ip       = GetBindedIpAddress(args);
            Follower follower = null;

            if (!String.IsNullOrEmpty(ip))
            {
                var       ipPartsArr = ip.Split(new Char[] { '.' }, StringSplitOptions.RemoveEmptyEntries);
                byte[]    ipParts    = ipPartsArr.Select(s => Convert.ToByte(s, 10)).ToArray();
                IPAddress ipAddress  = new IPAddress(ipParts);
                follower = new Follower(ipAddress);
            }
            else
            {
                follower = new Follower();
            }
            NodeRegistryCache.GetInstance().RegisterCurrentNode(follower);
            Logger.Log(string.Format("Node added : {0}", follower.ToString()));
            RequestListener.StartListeningOnPorts();
            RegisterCluster(args);
            follower.StartUp();
            follower.StartNetworkBootstrap();
        }
        private static void HeartbeatReadCallback(IAsyncResult ar)
        {
            try
            {
                String      content = String.Empty;
                StateObject state   = (StateObject)ar.AsyncState;
                Socket      handler = state.workSocket;

                // Read data from the client socket.
                int bytesRead = handler.EndReceive(ar);

                if (bytesRead > 0)
                {
                    state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, bytesRead));
                    content = state.sb.ToString();
                    if (content.IndexOf("<EOF>") > -1)
                    {
                        NodeRegistryCache.GetInstance().NofifyHeartbeatReceived(content);
                    }
                    else
                    {
                        // Not all data received. Get more.
                        handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
                                             new AsyncCallback(HeartbeatReadCallback), state);
                    }
                }
            }
            catch (SocketException sExp)
            {
                Logger.Log("Error :: " + sExp.Message);
            }
            catch (Exception exp)
            {
                Logger.Log("Error :: " + exp.Message);
            }
        }
        private static void WaitForRequestVoteRPCResponseAsync()
        {
            IPEndPoint candidateLisResponseEndPoint    = new IPEndPoint(NodeRegistryCache.GetInstance().IP, CANDIDATE_PORT_NUMBER);
            Socket     candidateResponseListenerSocket = new Socket(candidateLisResponseEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);

            try
            {
                candidateResponseListenerSocket.Bind(candidateLisResponseEndPoint);
                Logger.Log("INFO :: Candidate started Listening for REQUEST VOTE RPC (RES) on port " + CANDIDATE_PORT_NUMBER + " .");
                candidateResponseListenerSocket.Listen(1000);
                while (true)
                {
                    candidateAsyncHandler.Reset();
                    candidateResponseListenerSocket.BeginAccept(CandidateRVResponseListenerAcceptCallback, candidateResponseListenerSocket);
                    candidatePortSwitch.Set();
                    candidateAsyncHandler.WaitOne();
                }
            }
            catch (Exception exp)
            {
                Logger.Log(exp.Message);
                candidatePortSwitch.Set();
            }
        }