use of org.apache.ratis.server.impl.RaftServerImpl in project incubator-ratis by apache.
the class RetryCacheTests method testBasicRetry.
/**
* make sure the retry cache can correct capture the retry from a client,
* and returns the result from the previous request
*/
@Test
public void testBasicRetry() throws Exception {
final MiniRaftCluster cluster = getCluster();
RaftTestUtil.waitForLeader(cluster);
final RaftPeerId leaderId = cluster.getLeaderAndSendFirstMessage().getId();
long oldLastApplied = cluster.getLeader().getState().getLastAppliedIndex();
final RaftClient client = cluster.createClient(leaderId);
final RaftClientRpc rpc = client.getClientRpc();
final long callId = 999;
final long seqNum = 111;
RaftClientRequest r = cluster.newRaftClientRequest(client.getId(), leaderId, callId, seqNum, new SimpleMessage("message"));
RaftClientReply reply = rpc.sendRequest(r);
Assert.assertEquals(callId, reply.getCallId());
Assert.assertTrue(reply.isSuccess());
// retry with the same callId
for (int i = 0; i < 5; i++) {
reply = rpc.sendRequest(r);
Assert.assertEquals(client.getId(), reply.getClientId());
Assert.assertEquals(callId, reply.getCallId());
Assert.assertTrue(reply.isSuccess());
}
long leaderApplied = cluster.getLeader().getState().getLastAppliedIndex();
// make sure retry cache has the entry
for (RaftServerImpl server : cluster.iterateServerImpls()) {
LOG.info("check server " + server.getId());
if (server.getState().getLastAppliedIndex() < leaderApplied) {
Thread.sleep(1000);
}
Assert.assertEquals(2, RaftServerTestUtil.getRetryCacheSize(server));
Assert.assertNotNull(RaftServerTestUtil.getRetryEntry(server, client.getId(), callId));
// make sure there is only one log entry committed
Assert.assertEquals(oldLastApplied + 1, server.getState().getLastAppliedIndex());
}
client.close();
}
use of org.apache.ratis.server.impl.RaftServerImpl in project incubator-ratis by apache.
the class TestRaftStateMachineException method testRetryOnStateMachineException.
@Test
public void testRetryOnStateMachineException() throws Exception {
setAndStart(cluster);
final RaftPeerId leaderId = cluster.getLeaderAndSendFirstMessage(true).getId();
long oldLastApplied = cluster.getLeader().getState().getLastAppliedIndex();
final RaftClient client = cluster.createClient(leaderId);
final RaftClientRpc rpc = client.getClientRpc();
final long callId = 999;
final long seqNum = 111;
RaftClientRequest r = cluster.newRaftClientRequest(client.getId(), leaderId, callId, seqNum, new SimpleMessage("message"));
RaftClientReply reply = rpc.sendRequest(r);
Assert.assertFalse(reply.isSuccess());
Assert.assertNotNull(reply.getStateMachineException());
// retry with the same callId
for (int i = 0; i < 5; i++) {
reply = rpc.sendRequest(r);
Assert.assertEquals(client.getId(), reply.getClientId());
Assert.assertEquals(callId, reply.getCallId());
Assert.assertFalse(reply.isSuccess());
Assert.assertNotNull(reply.getStateMachineException());
}
long leaderApplied = cluster.getLeader().getState().getLastAppliedIndex();
// make sure retry cache has the entry
for (RaftServerImpl server : cluster.iterateServerImpls()) {
LOG.info("check server " + server.getId());
if (server.getState().getLastAppliedIndex() < leaderApplied) {
Thread.sleep(1000);
}
Assert.assertNotNull(RaftServerTestUtil.getRetryEntry(server, client.getId(), callId));
Assert.assertEquals(oldLastApplied + 1, server.getState().getLastAppliedIndex());
}
client.close();
}
use of org.apache.ratis.server.impl.RaftServerImpl in project incubator-ratis by apache.
the class TestRaftStream method testKillLeader.
/**
* Write while leader is killed
*/
@Test
public void testKillLeader() throws Exception {
LOG.info("Running testChangeLeader");
GrpcConfigKeys.OutputStream.setBufferSize(prop, SizeInBytes.valueOf(4));
cluster = MiniRaftClusterWithGRpc.FACTORY.newCluster(NUM_SERVERS, prop);
cluster.start();
final RaftServerImpl leader = waitForLeader(cluster);
final AtomicBoolean running = new AtomicBoolean(true);
final AtomicReference<Boolean> success = new AtomicReference<>();
final AtomicInteger result = new AtomicInteger(0);
final CountDownLatch latch = new CountDownLatch(1);
new Thread(() -> {
LOG.info("Writer thread starts");
int count = 0;
try (RaftOutputStream out = new RaftOutputStream(prop, ClientId.randomId(), cluster.getGroup(), leader.getId())) {
while (running.get()) {
out.write(toBytes(count++));
Thread.sleep(10);
}
success.set(true);
result.set(count);
} catch (Exception e) {
LOG.info("Got exception when writing", e);
success.set(false);
} finally {
latch.countDown();
}
}).start();
// force change the leader
Thread.sleep(500);
RaftTestUtil.waitAndKillLeader(cluster, true);
final RaftServerImpl newLeader = waitForLeader(cluster);
Assert.assertNotEquals(leader.getId(), newLeader.getId());
Thread.sleep(500);
running.set(false);
latch.await(5, TimeUnit.SECONDS);
LOG.info("Writer success? " + success.get());
Assert.assertTrue(success.get());
// total number of tx should be >= result + 2, where 2 means two NoOp from
// leaders. It may be larger than result+2 because the client may resend
// requests and we do not have retry cache on servers yet.
LOG.info("last applied index: {}. total number of requests: {}", newLeader.getState().getLastAppliedIndex(), result.get());
Assert.assertTrue(newLeader.getState().getLastAppliedIndex() >= result.get() + 1);
}
use of org.apache.ratis.server.impl.RaftServerImpl in project incubator-ratis by apache.
the class TestRaftStream method testSimpleWrite.
@Test
public void testSimpleWrite() throws Exception {
final int numRequests = 500;
LOG.info("Running testSimpleWrite, numRequests=" + numRequests);
// default 64K is too large for a test
GrpcConfigKeys.OutputStream.setBufferSize(prop, SizeInBytes.valueOf(4));
cluster = MiniRaftClusterWithGRpc.FACTORY.newCluster(NUM_SERVERS, prop);
cluster.start();
RaftServerImpl leader = waitForLeader(cluster);
try (RaftOutputStream out = new RaftOutputStream(prop, ClientId.randomId(), cluster.getGroup(), leader.getId())) {
for (int i = 0; i < numRequests; i++) {
// generate requests
out.write(toBytes(i));
}
}
// check the leader's raft log
final RaftLog raftLog = leader.getState().getLog();
final AtomicInteger i = new AtomicInteger();
checkLog(raftLog, numRequests, () -> toBytes(i.getAndIncrement()));
}
use of org.apache.ratis.server.impl.RaftServerImpl in project incubator-ratis by apache.
the class TestCacheEviction method testEvictionInSegmentedLog.
@Test
public void testEvictionInSegmentedLog() throws Exception {
final RaftProperties prop = new RaftProperties();
prop.setClass(MiniRaftCluster.STATEMACHINE_CLASS_KEY, SimpleStateMachine4Testing.class, StateMachine.class);
RaftServerConfigKeys.Log.setSegmentSizeMax(prop, SizeInBytes.valueOf("8KB"));
RaftServerConfigKeys.Log.setPreallocatedSize(prop, SizeInBytes.valueOf("8KB"));
final RaftPeerId peerId = RaftPeerId.valueOf("s0");
final int maxCachedNum = RaftServerConfigKeys.Log.maxCachedSegmentNum(prop);
File storageDir = getTestDir();
RaftServerConfigKeys.setStorageDir(prop, storageDir);
RaftStorage storage = new RaftStorage(storageDir, RaftServerConstants.StartupOption.REGULAR);
RaftServerImpl server = Mockito.mock(RaftServerImpl.class);
ServerState state = Mockito.mock(ServerState.class);
Mockito.when(server.getState()).thenReturn(state);
Mockito.when(server.getFollowerNextIndices()).thenReturn(new long[] {});
Mockito.when(state.getLastAppliedIndex()).thenReturn(0L);
SegmentedRaftLog raftLog = new SegmentedRaftLog(peerId, server, storage, -1, prop);
raftLog.open(RaftServerConstants.INVALID_LOG_INDEX, null);
List<SegmentRange> slist = TestSegmentedRaftLog.prepareRanges(maxCachedNum, 7, 0);
LogEntryProto[] entries = generateEntries(slist);
raftLog.append(entries).forEach(CompletableFuture::join);
// check the current cached segment number: the last segment is still open
Assert.assertEquals(maxCachedNum - 1, raftLog.getRaftLogCache().getCachedSegmentNum());
Mockito.when(server.getFollowerNextIndices()).thenReturn(new long[] { 21, 40, 40 });
Mockito.when(state.getLastAppliedIndex()).thenReturn(35L);
slist = TestSegmentedRaftLog.prepareRanges(2, 7, 7 * maxCachedNum);
entries = generateEntries(slist);
raftLog.append(entries).forEach(CompletableFuture::join);
// check the cached segment number again. since the slowest follower is on
// index 21, the eviction should happen and evict 3 segments
Assert.assertEquals(maxCachedNum + 1 - 3, raftLog.getRaftLogCache().getCachedSegmentNum());
}
Aggregations