Ejemplo n.º 1
0
        void AppendEntries(RaftMessage message)
        {
            //Ignore if message.term < term
            if (message.Term < currentTerm)
            {
                Console.Out.WriteLine("Old term detected. Discarding append entries.");
                return;
            }

            if (string.IsNullOrEmpty(message.Data))
            {
                Console.Out.WriteLine("FOLLOWING ORDERS");
                leader          = message.Sender;
                state           = RaftState.Follower;
                votedFor        = null;
                electionTimeout = DateTime.UtcNow.AddMilliseconds(electionWaitPeriod);
            }
            else
            {
                var data              = message.Data.Split('-');
                var prevLogIndex      = Int32.Parse(data[0]);
                var prevLogTerm       = Int32.Parse(data[1]);
                var leaderCommitIndex = Int32.Parse(data[2]);

                //ignore if log doesn't contain an entry at prevLogIndex whos term is equal to prevLogTerm
                if (log[prevLogIndex] != null)
                {
                    if (log[prevLogIndex].Term != prevLogTerm)
                    {
                        Console.Out.WriteLine("Incorrect term for previous log entry detected. Discarding append entries.");
                        return;
                    }
                }

                Console.Out.WriteLine("DOING WORK");

                //If entry conflicts, delete entry and following entries

                /*
                 * if (log[RaftLogEntry.Index] != null && log[RaftLogEntry.Index].Term != RaftLogEntry.Term)
                 * {
                 *  var toBeDeleted = log.Where(x => x.Index >= RaftLogEntry.Index).Select(x => x.Index).ToList();
                 *  foreach(var index in toBeDeleted)
                 *  {
                 *      log[index] = null;
                 *  }
                 * }
                 */

                //Append all new entries to log

                /*
                 * if(leaderCommitIndex > commitIndex)
                 * {
                 *  commitIndex = Math.Min(leaderCommitIndex, lastNewEntry);
                 * }
                 */
            }
        }
Ejemplo n.º 2
0
        public BlockingCollection <RaftMessage> StartIncoming()
        {
            if (inStarted)
            {
                throw new Exception("You can only start the comms package input once.");
            }

            LocalHost = LocalIPAddress().ToString() + ":" + listenport;

            Task.Factory.StartNew(() =>
            {
                string message;
                try
                {
                    IPEndPoint localEndpoint  = new IPEndPoint(LocalIPAddress(), listenport);
                    IPEndPoint remoteEndpoint = new IPEndPoint(IPAddress.Any, 0);

                    UdpClient server = new UdpClient(localEndpoint);

                    Console.Out.WriteLine("I'm listening on " + LocalHost);

                    while (true)
                    {
                        message = Encoding.UTF8.GetString(server.Receive(ref remoteEndpoint));

                        Console.WriteLine("COM: Got message {0}", message);
                        var dataParts = message.Split('|');
                        if (dataParts.Count() < 3)
                        {
                            continue;
                        }
                        var type   = (RaftMessageType)Int32.Parse(dataParts[0]);
                        var sender = dataParts[1];
                        var term   = Int32.Parse(dataParts[2]);

                        var data = (dataParts.Count() > 3 ? dataParts[3] : "");

                        var msg = new RaftMessage
                        {
                            Type   = type,
                            Term   = term,
                            Sender = sender,
                            Data   = data
                        };

                        incoming.Add(msg);
                    }
                }
                catch (Exception ex)
                {
                    Console.Out.Write(ex);
                }
            }, TaskCreationOptions.LongRunning);

            inStarted = true;

            return(incoming);
        }
Ejemplo n.º 3
0
        public void StartIncoming()
        {
            // ZMQ Context, server socket
            context   = ZmqContext.Create();
            LocalHost = LocalIPAddress() + ":" + listenport;

            Task.Factory.StartNew(() =>
            {
                string message;
                try
                {
                    ZmqSocket server = context.CreateSocket(ZeroMQ.SocketType.REP);
                    server.Bind("tcp://" + LocalHost);

                    Console.Out.WriteLine("I'm listening on " + LocalHost);

                    while (true)
                    {
                        message = server.Receive(Encoding.Unicode);
                        if (message.Equals("OVER"))
                        {
                            continue;
                        }

                        Console.WriteLine("COM: Got message {0}", message);
                        var dataParts = message.Split('|');
                        if (dataParts.Count() < 2)
                        {
                            continue;
                        }
                        var type   = (RaftMessageType)Int32.Parse(dataParts[0]);
                        var sender = dataParts[1];

                        var data = (dataParts.Count() > 2 ? dataParts[2] : "");

                        var msg = new RaftMessage
                        {
                            Type   = type,
                            Sender = sender,
                            Data   = data
                        };

                        incoming.Add(msg);

                        server.Send("OVER", Encoding.UTF8);
                    }
                }
                catch (Exception ex)
                {
                    Console.Out.Write(ex);
                }
            }, TaskCreationOptions.LongRunning);
        }
Ejemplo n.º 4
0
        private void Send(RaftMessageType type, string destination, string data)
        {
            var msg = new RaftMessage
            {
                Type        = type,
                Term        = currentTerm,
                Destination = destination,
                Data        = data
            };

            outputQueue.Add(msg);
        }
Ejemplo n.º 5
0
        void Vote(RaftMessage message)
        {
            var requester = message.Sender;

            if (message.Term < currentTerm)
            {
                Send(RaftMessageType.Vote, requester, "0");
                return;
            }

            var logData      = message.Data.Split('-');
            var lastLogIndex = Int32.Parse(logData[0]);
            var lastLogTerm  = Int32.Parse(logData[1]);

            if (votedFor == null || (lastLogIndex >= lastApplied && (lastApplied == 0 ? true : log[lastApplied].Term >= lastLogTerm)))
            {
                Console.Out.WriteLine("I voted for " + requester);
                votedFor        = requester;
                electionTimeout = DateTime.UtcNow.AddMilliseconds(electionWaitPeriod);
                Send(RaftMessageType.Vote, requester, "1");
            }
        }
Ejemplo n.º 6
0
        private void VoteReceived(RaftMessage message)
        {
            if (message.Data == "1")
            {
                if (state != RaftState.Leader)
                {
                    var from = message.Sender;
                    Console.Out.WriteLine("Got vote from " + from);

                    remoteNodes[from].VoteGranted = true;
                    //me + others = total / 2 + 1 = quora
                    var votesForMe  = 1 + remoteNodes.Values.Where(x => x.VoteGranted).Count();
                    var votesNeeded = Math.Floor((double)((1 + remoteNodes.Keys.Count())) / 2) + 1;

                    Console.Out.WriteLine("I need " + votesNeeded + " votes. I have " + votesForMe + " votes");

                    if (votesForMe >= votesNeeded)
                    {
                        BecomeLeader();
                    }
                }
            }
        }
Ejemplo n.º 7
0
        private void ProcessMessage(RaftMessage message)
        {
            //If any message has a bigger term, set term = message.term and become follower
            if (message.Term > currentTerm)
            {
                state       = RaftState.Follower;
                currentTerm = message.Term;
            }

            switch (message.Type)
            {
            case RaftMessageType.Vote:
                VoteReceived(message);
                break;

            case RaftMessageType.RequestVote:
                Vote(message);
                break;

            case RaftMessageType.AppendEntries:
                AppendEntries(message);
                break;
            }
        }