Search in sources :

Example 41 with RaftLogEntry

use of org.neo4j.causalclustering.core.consensus.log.RaftLogEntry in project neo4j by neo4j.

the class AppendEntriesRequestTest method bootstrappedLog.

private RaftLog bootstrappedLog() throws IOException {
    InMemoryRaftLog raftLog = new InMemoryRaftLog();
    raftLog.append(new RaftLogEntry(0, content()));
    return raftLog;
}
Also used : InMemoryRaftLog(org.neo4j.causalclustering.core.consensus.log.InMemoryRaftLog) RaftLogEntry(org.neo4j.causalclustering.core.consensus.log.RaftLogEntry)

Example 42 with RaftLogEntry

use of org.neo4j.causalclustering.core.consensus.log.RaftLogEntry in project neo4j by neo4j.

the class AppendingTest method shouldNotAllowTruncationAtCommit.

@Test
public void shouldNotAllowTruncationAtCommit() throws Exception {
    // given
    long commitIndex = 5;
    long localTermForAllEntries = 1L;
    Outcome outcome = mock(Outcome.class);
    ReadableRaftLog logMock = mock(ReadableRaftLog.class);
    // for simplicity, all entries are at term 1
    when(logMock.readEntryTerm(anyLong())).thenReturn(localTermForAllEntries);
    when(logMock.appendIndex()).thenReturn(commitIndex);
    ReadableRaftState state = mock(ReadableRaftState.class);
    when(state.entryLog()).thenReturn(logMock);
    when(state.commitIndex()).thenReturn(commitIndex);
    // when - then
    try {
        Appending.handleAppendEntriesRequest(state, outcome, new RaftMessages.AppendEntries.Request(aMember, localTermForAllEntries, commitIndex - 1, localTermForAllEntries, new RaftLogEntry[] { new RaftLogEntry(localTermForAllEntries + 1, ReplicatedInteger.valueOf(2)) }, commitIndex + 3), NullLog.getInstance());
        fail("Appending should not allow truncation at or before the commit index");
    } catch (IllegalStateException expected) {
    // ok
    }
}
Also used : ReadableRaftLog(org.neo4j.causalclustering.core.consensus.log.ReadableRaftLog) Outcome(org.neo4j.causalclustering.core.consensus.outcome.Outcome) ReadableRaftState(org.neo4j.causalclustering.core.consensus.state.ReadableRaftState) RaftLogEntry(org.neo4j.causalclustering.core.consensus.log.RaftLogEntry) Test(org.junit.Test)

Example 43 with RaftLogEntry

use of org.neo4j.causalclustering.core.consensus.log.RaftLogEntry in project neo4j by neo4j.

the class InFlightLogEntryReaderTest method shouldUseTheCacheWhenTheIndexIsPresent.

@Test
public void shouldUseTheCacheWhenTheIndexIsPresent() throws Exception {
    // given
    InFlightLogEntryReader reader = new InFlightLogEntryReader(raftLog, inFlightMap, clearCache);
    startingFromIndexReturnEntries(inFlightMap, logIndex, entry);
    startingFromIndexReturnEntries(raftLog, -1, null);
    // when
    RaftLogEntry raftLogEntry = reader.get(logIndex);
    // then
    assertEquals(entry, raftLogEntry);
    verify(inFlightMap).get(logIndex);
    assertCacheIsUpdated(inFlightMap, logIndex);
    verifyNoMoreInteractions(inFlightMap);
    verifyZeroInteractions(raftLog);
}
Also used : RaftLogEntry(org.neo4j.causalclustering.core.consensus.log.RaftLogEntry) Test(org.junit.Test)

Example 44 with RaftLogEntry

use of org.neo4j.causalclustering.core.consensus.log.RaftLogEntry in project neo4j by neo4j.

the class RaftMessageEncoder method encode.

@Override
protected synchronized void encode(ChannelHandlerContext ctx, RaftMessages.ClusterIdAwareMessage decoratedMessage, ByteBuf out) throws Exception {
    RaftMessages.RaftMessage message = decoratedMessage.message();
    ClusterId clusterId = decoratedMessage.clusterId();
    MemberId.Marshal memberMarshal = new MemberId.Marshal();
    NetworkFlushableByteBuf channel = new NetworkFlushableByteBuf(out);
    ClusterId.Marshal.INSTANCE.marshal(clusterId, channel);
    channel.putInt(message.type().ordinal());
    memberMarshal.marshal(message.from(), channel);
    if (message instanceof RaftMessages.Vote.Request) {
        RaftMessages.Vote.Request voteRequest = (RaftMessages.Vote.Request) message;
        memberMarshal.marshal(voteRequest.candidate(), channel);
        channel.putLong(voteRequest.term());
        channel.putLong(voteRequest.lastLogIndex());
        channel.putLong(voteRequest.lastLogTerm());
    } else if (message instanceof RaftMessages.Vote.Response) {
        RaftMessages.Vote.Response voteResponse = (RaftMessages.Vote.Response) message;
        channel.putLong(voteResponse.term());
        channel.put((byte) (voteResponse.voteGranted() ? 1 : 0));
    } else if (message instanceof RaftMessages.AppendEntries.Request) {
        RaftMessages.AppendEntries.Request appendRequest = (RaftMessages.AppendEntries.Request) message;
        channel.putLong(appendRequest.leaderTerm());
        channel.putLong(appendRequest.prevLogIndex());
        channel.putLong(appendRequest.prevLogTerm());
        channel.putLong(appendRequest.leaderCommit());
        channel.putLong(appendRequest.entries().length);
        for (RaftLogEntry raftLogEntry : appendRequest.entries()) {
            channel.putLong(raftLogEntry.term());
            marshal.marshal(raftLogEntry.content(), channel);
        }
    } else if (message instanceof RaftMessages.AppendEntries.Response) {
        RaftMessages.AppendEntries.Response appendResponse = (RaftMessages.AppendEntries.Response) message;
        channel.putLong(appendResponse.term());
        channel.put((byte) (appendResponse.success() ? 1 : 0));
        channel.putLong(appendResponse.matchIndex());
        channel.putLong(appendResponse.appendIndex());
    } else if (message instanceof RaftMessages.NewEntry.Request) {
        RaftMessages.NewEntry.Request newEntryRequest = (RaftMessages.NewEntry.Request) message;
        marshal.marshal(newEntryRequest.content(), channel);
    } else if (message instanceof RaftMessages.Heartbeat) {
        RaftMessages.Heartbeat heartbeat = (RaftMessages.Heartbeat) message;
        channel.putLong(heartbeat.leaderTerm());
        channel.putLong(heartbeat.commitIndexTerm());
        channel.putLong(heartbeat.commitIndex());
    } else if (message instanceof RaftMessages.HeartbeatResponse) {
    //Heartbeat Response does not have any data attached to it.
    } else if (message instanceof RaftMessages.LogCompactionInfo) {
        RaftMessages.LogCompactionInfo logCompactionInfo = (RaftMessages.LogCompactionInfo) message;
        channel.putLong(logCompactionInfo.leaderTerm());
        channel.putLong(logCompactionInfo.prevIndex());
    } else {
        throw new IllegalArgumentException("Unknown message type: " + message);
    }
}
Also used : NetworkFlushableByteBuf(org.neo4j.causalclustering.messaging.NetworkFlushableByteBuf) ClusterId(org.neo4j.causalclustering.identity.ClusterId) RaftMessages(org.neo4j.causalclustering.core.consensus.RaftMessages) RaftLogEntry(org.neo4j.causalclustering.core.consensus.log.RaftLogEntry) MemberId(org.neo4j.causalclustering.identity.MemberId)

Example 45 with RaftLogEntry

use of org.neo4j.causalclustering.core.consensus.log.RaftLogEntry in project neo4j by neo4j.

the class RaftMessageDecoder method decode.

@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf buffer, List<Object> list) throws Exception {
    ReadableChannel channel = new NetworkReadableClosableChannelNetty4(buffer);
    ClusterId clusterId = ClusterId.Marshal.INSTANCE.unmarshal(channel);
    int messageTypeWire = channel.getInt();
    RaftMessages.Type[] values = RaftMessages.Type.values();
    RaftMessages.Type messageType = values[messageTypeWire];
    MemberId from = retrieveMember(channel);
    RaftMessages.RaftMessage result;
    if (messageType.equals(VOTE_REQUEST)) {
        MemberId candidate = retrieveMember(channel);
        long term = channel.getLong();
        long lastLogIndex = channel.getLong();
        long lastLogTerm = channel.getLong();
        result = new RaftMessages.Vote.Request(from, term, candidate, lastLogIndex, lastLogTerm);
    } else if (messageType.equals(VOTE_RESPONSE)) {
        long term = channel.getLong();
        boolean voteGranted = channel.get() == 1;
        result = new RaftMessages.Vote.Response(from, term, voteGranted);
    } else if (messageType.equals(APPEND_ENTRIES_REQUEST)) {
        // how many
        long term = channel.getLong();
        long prevLogIndex = channel.getLong();
        long prevLogTerm = channel.getLong();
        long leaderCommit = channel.getLong();
        long count = channel.getLong();
        RaftLogEntry[] entries = new RaftLogEntry[(int) count];
        for (int i = 0; i < count; i++) {
            long entryTerm = channel.getLong();
            final ReplicatedContent content = marshal.unmarshal(channel);
            entries[i] = new RaftLogEntry(entryTerm, content);
        }
        result = new RaftMessages.AppendEntries.Request(from, term, prevLogIndex, prevLogTerm, entries, leaderCommit);
    } else if (messageType.equals(APPEND_ENTRIES_RESPONSE)) {
        long term = channel.getLong();
        boolean success = channel.get() == 1;
        long matchIndex = channel.getLong();
        long appendIndex = channel.getLong();
        result = new RaftMessages.AppendEntries.Response(from, term, success, matchIndex, appendIndex);
    } else if (messageType.equals(NEW_ENTRY_REQUEST)) {
        ReplicatedContent content = marshal.unmarshal(channel);
        result = new RaftMessages.NewEntry.Request(from, content);
    } else if (messageType.equals(HEARTBEAT)) {
        long leaderTerm = channel.getLong();
        long commitIndexTerm = channel.getLong();
        long commitIndex = channel.getLong();
        result = new RaftMessages.Heartbeat(from, leaderTerm, commitIndex, commitIndexTerm);
    } else if (messageType.equals(HEARTBEAT_RESPONSE)) {
        result = new RaftMessages.HeartbeatResponse(from);
    } else if (messageType.equals(LOG_COMPACTION_INFO)) {
        long leaderTerm = channel.getLong();
        long prevIndex = channel.getLong();
        result = new RaftMessages.LogCompactionInfo(from, leaderTerm, prevIndex);
    } else {
        throw new IllegalArgumentException("Unknown message type");
    }
    list.add(new RaftMessages.ClusterIdAwareMessage(clusterId, result));
}
Also used : ReadableChannel(org.neo4j.storageengine.api.ReadableChannel) NetworkReadableClosableChannelNetty4(org.neo4j.causalclustering.messaging.NetworkReadableClosableChannelNetty4) RaftLogEntry(org.neo4j.causalclustering.core.consensus.log.RaftLogEntry) MemberId(org.neo4j.causalclustering.identity.MemberId) ClusterId(org.neo4j.causalclustering.identity.ClusterId) RaftMessages(org.neo4j.causalclustering.core.consensus.RaftMessages) ReplicatedContent(org.neo4j.causalclustering.core.replication.ReplicatedContent)

Aggregations

RaftLogEntry (org.neo4j.causalclustering.core.consensus.log.RaftLogEntry)87 Test (org.junit.Test)69 Outcome (org.neo4j.causalclustering.core.consensus.outcome.Outcome)27 InMemoryRaftLog (org.neo4j.causalclustering.core.consensus.log.InMemoryRaftLog)25 RaftState (org.neo4j.causalclustering.core.consensus.state.RaftState)20 RaftMessages (org.neo4j.causalclustering.core.consensus.RaftMessages)12 RaftLog (org.neo4j.causalclustering.core.consensus.log.RaftLog)10 ReadableRaftState (org.neo4j.causalclustering.core.consensus.state.ReadableRaftState)10 AppendLogEntry (org.neo4j.causalclustering.core.consensus.outcome.AppendLogEntry)8 NewLeaderBarrier (org.neo4j.causalclustering.core.consensus.NewLeaderBarrier)7 AppendEntries (org.neo4j.causalclustering.core.consensus.RaftMessages.AppendEntries)7 MemberId (org.neo4j.causalclustering.identity.MemberId)7 InOrder (org.mockito.InOrder)6 RaftLogCursor (org.neo4j.causalclustering.core.consensus.log.RaftLogCursor)6 ReadableRaftLog (org.neo4j.causalclustering.core.consensus.log.ReadableRaftLog)5 RaftTestGroup (org.neo4j.causalclustering.core.consensus.membership.RaftTestGroup)5 BatchAppendLogEntries (org.neo4j.causalclustering.core.consensus.outcome.BatchAppendLogEntries)5 ShipCommand (org.neo4j.causalclustering.core.consensus.outcome.ShipCommand)5 TruncateLogCommand (org.neo4j.causalclustering.core.consensus.outcome.TruncateLogCommand)5 File (java.io.File)4