Example #1
0
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#:
//ORIGINAL LINE: public org.neo4j.causalclustering.core.consensus.outcome.Outcome handle(org.neo4j.causalclustering.core.consensus.RaftMessages_PreVote_Response res, org.neo4j.causalclustering.core.consensus.outcome.Outcome outcome, org.neo4j.causalclustering.core.consensus.state.ReadableRaftState ctx, org.neo4j.logging.Log log) throws java.io.IOException
            public override Outcome Handle(Org.Neo4j.causalclustering.core.consensus.RaftMessages_PreVote_Response res, Outcome outcome, ReadableRaftState ctx, Log log)
            {
                if (res.Term() > ctx.Term())
                {
                    outcome.NextTerm    = res.Term();
                    outcome.PreElection = false;
                    log.Info("Aborting pre-election after receiving pre-vote response from %s at term %d (I am at %d)", res.From(), res.Term(), ctx.Term());
                    return(outcome);
                }
                else if (res.Term() < ctx.Term() || !res.VoteGranted())
                {
                    return(outcome);
                }

                if (!res.From().Equals(ctx.Myself()))
                {
                    outcome.AddPreVoteForMe(res.From());
                }

                if (isQuorum(ctx.VotingMembers(), outcome.PreVotesForMe))
                {
                    outcome.RenewElectionTimeout();
                    outcome.PreElection = false;
                    if (Election.StartRealElection(ctx, outcome, log))
                    {
                        outcome.NextRole = CANDIDATE;
                        log.Info("Moving to CANDIDATE state after successful pre-election stage");
                    }
                }
                return(outcome);
            }
Example #2
0
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#:
//ORIGINAL LINE: public static boolean startPreElection(org.neo4j.causalclustering.core.consensus.state.ReadableRaftState ctx, org.neo4j.causalclustering.core.consensus.outcome.Outcome outcome, org.neo4j.logging.Log log) throws java.io.IOException
        public static bool StartPreElection(ReadableRaftState ctx, Outcome outcome, Log log)
        {
            ISet <MemberId> currentMembers = ctx.VotingMembers();

            if (currentMembers == null || !currentMembers.Contains(ctx.Myself()))
            {
                log.Info("Pre-election attempted but not started, current members are %s, I am %s", currentMembers, ctx.Myself());
                return(false);
            }

            Org.Neo4j.causalclustering.core.consensus.RaftMessages_PreVote_Request preVoteForMe = new Org.Neo4j.causalclustering.core.consensus.RaftMessages_PreVote_Request(ctx.Myself(), outcome.Term, ctx.Myself(), ctx.EntryLog().appendIndex(), ctx.EntryLog().readEntryTerm(ctx.EntryLog().appendIndex()));

            currentMembers.Where(member => !member.Equals(ctx.Myself())).ForEach(member => outcome.addOutgoingMessage(new Org.Neo4j.causalclustering.core.consensus.RaftMessages_Directed(member, preVoteForMe)));

            log.Info("Pre-election started with: %s and members: %s", preVoteForMe, currentMembers);
            return(true);
        }
Example #3
0
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#:
//ORIGINAL LINE: static void sendHeartbeats(org.neo4j.causalclustering.core.consensus.state.ReadableRaftState ctx, org.neo4j.causalclustering.core.consensus.outcome.Outcome outcome) throws java.io.IOException
        internal static void SendHeartbeats(ReadableRaftState ctx, Outcome outcome)
        {
            long commitIndex                 = ctx.CommitIndex();
            long commitIndexTerm             = ctx.EntryLog().readEntryTerm(commitIndex);
            RaftMessages_Heartbeat heartbeat = new RaftMessages_Heartbeat(ctx.Myself(), ctx.Term(), commitIndex, commitIndexTerm);

            foreach (MemberId to in ReplicationTargets(ctx))
            {
                outcome.AddOutgoingMessage(new Org.Neo4j.causalclustering.core.consensus.RaftMessages_Directed(to, heartbeat));
            }
        }
Example #4
0
            public override Outcome Handle(Org.Neo4j.causalclustering.core.consensus.RaftMessages_Timeout_Election election, Outcome outcome, ReadableRaftState ctx, Log log)
            {
                log.Info("Election timeout triggered but refusing to be leader");
                ISet <MemberId> memberIds = ctx.VotingMembers();

                if (memberIds != null && memberIds.Contains(ctx.Myself()))
                {
                    outcome.PreElection = true;
                }
                return(outcome);
            }
Example #5
0
//JAVA TO C# CONVERTER WARNING: 'final' parameters are ignored unless the option to convert to C# 7.2 'in' parameters is selected:
//ORIGINAL LINE: private static Iterable<org.neo4j.causalclustering.identity.MemberId> replicationTargets(final org.neo4j.causalclustering.core.consensus.state.ReadableRaftState ctx)
        private static IEnumerable <MemberId> ReplicationTargets(ReadableRaftState ctx)
        {
            return(new FilteringIterable <MemberId>(ctx.ReplicationMembers(), member => !member.Equals(ctx.Myself())));
        }
Example #6
0
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#:
//ORIGINAL LINE: ComparableRaftState(org.neo4j.causalclustering.core.consensus.state.ReadableRaftState original) throws java.io.IOException
        internal ComparableRaftState(ReadableRaftState original) : this(original.Myself(), original.VotingMembers(), original.ReplicationMembers(), original.RefusesToBeLeader(), new ComparableRaftLog(original.EntryLog()), new ConsecutiveInFlightCache(), NullLogProvider.Instance)
        {
        }
Example #7
0
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#:
//ORIGINAL LINE: static void handleAppendEntriesRequest(org.neo4j.causalclustering.core.consensus.state.ReadableRaftState state, org.neo4j.causalclustering.core.consensus.outcome.Outcome outcome, org.neo4j.causalclustering.core.consensus.RaftMessages_AppendEntries_Request request, org.neo4j.logging.Log log) throws java.io.IOException
        internal static void HandleAppendEntriesRequest(ReadableRaftState state, Outcome outcome, Org.Neo4j.causalclustering.core.consensus.RaftMessages_AppendEntries_Request request, Log log)
        {
            if (request.LeaderTerm() < state.Term())
            {
                Org.Neo4j.causalclustering.core.consensus.RaftMessages_AppendEntries_Response appendResponse = new Org.Neo4j.causalclustering.core.consensus.RaftMessages_AppendEntries_Response(state.Myself(), state.Term(), false, -1, state.EntryLog().appendIndex());

                outcome.AddOutgoingMessage(new Org.Neo4j.causalclustering.core.consensus.RaftMessages_Directed(request.From(), appendResponse));
                return;
            }

            outcome.PreElection  = false;
            outcome.NextTerm     = request.LeaderTerm();
            outcome.Leader       = request.From();
            outcome.LeaderCommit = request.LeaderCommit();

            if (!Follower.LogHistoryMatches(state, request.PrevLogIndex(), request.PrevLogTerm()))
            {
                Debug.Assert(request.PrevLogIndex() > -1 && request.PrevLogTerm() > -1);
                Org.Neo4j.causalclustering.core.consensus.RaftMessages_AppendEntries_Response appendResponse = new Org.Neo4j.causalclustering.core.consensus.RaftMessages_AppendEntries_Response(state.Myself(), request.LeaderTerm(), false, -1, state.EntryLog().appendIndex());

                outcome.AddOutgoingMessage(new Org.Neo4j.causalclustering.core.consensus.RaftMessages_Directed(request.From(), appendResponse));
                return;
            }

            long baseIndex = request.PrevLogIndex() + 1;
            int  offset;

            /* Find possible truncation point. */
            for (offset = 0; offset < request.Entries().Length; offset++)
            {
                long logIndex = baseIndex + offset;
                long logTerm  = state.EntryLog().readEntryTerm(logIndex);

                if (logIndex > state.EntryLog().appendIndex())
                {
                    // entry doesn't exist because it's beyond the current log end, so we can go ahead and append
                    break;
                }
                else if (logIndex < state.EntryLog().prevIndex())
                {
                    // entry doesn't exist because it's before the earliest known entry, so continue with the next one
                    continue;
                }
                else if (logTerm != request.Entries()[offset].term())
                {
                    /*
                     * the entry's index falls within our current range and the term doesn't match what we know. We must
                     * truncate.
                     */
                    if (logIndex <= state.CommitIndex())                                // first, assert that we haven't committed what we are about to truncate
                    {
                        throw new System.InvalidOperationException(format("Cannot truncate entry at index %d with term %d when commit index is at %d", logIndex, logTerm, state.CommitIndex()));
                    }
                    outcome.AddLogCommand(new TruncateLogCommand(logIndex));
                    break;
                }
            }

            if (offset < request.Entries().Length)
            {
                outcome.AddLogCommand(new BatchAppendLogEntries(baseIndex, offset, request.Entries()));
            }

            Follower.CommitToLogOnUpdate(state, request.PrevLogIndex() + request.Entries().Length, request.LeaderCommit(), outcome);

            long endMatchIndex = request.PrevLogIndex() + request.Entries().Length;               // this is the index of the last incoming entry

            Org.Neo4j.causalclustering.core.consensus.RaftMessages_AppendEntries_Response appendResponse = new Org.Neo4j.causalclustering.core.consensus.RaftMessages_AppendEntries_Response(state.Myself(), request.LeaderTerm(), true, endMatchIndex, endMatchIndex);
            outcome.AddOutgoingMessage(new Org.Neo4j.causalclustering.core.consensus.RaftMessages_Directed(request.From(), appendResponse));
        }