use of org.apache.ignite.raft.jraft.closure.SynchronizedClosure in project ignite-3 by apache.
the class ItNodeTest method startChangePeersThread.
private Future<?> startChangePeersThread(ChangeArg arg) {
Set<RaftError> expectedErrors = new HashSet<>();
expectedErrors.add(RaftError.EBUSY);
expectedErrors.add(RaftError.EPERM);
expectedErrors.add(RaftError.ECATCHUP);
ExecutorService executor = Executors.newSingleThreadExecutor();
executors.add(executor);
return Utils.runInThread(executor, () -> {
try {
while (!arg.stop) {
arg.c.waitLeader();
Node leader = arg.c.getLeader();
if (leader == null)
continue;
// select peers in random
Configuration conf = new Configuration();
if (arg.dontRemoveFirstPeer)
conf.addPeer(arg.peers.get(0));
for (int i = 0; i < arg.peers.size(); i++) {
boolean select = ThreadLocalRandom.current().nextInt(64) < 32;
if (select && !conf.contains(arg.peers.get(i)))
conf.addPeer(arg.peers.get(i));
}
if (conf.isEmpty()) {
LOG.warn("No peer has been selected");
continue;
}
SynchronizedClosure done = new SynchronizedClosure();
leader.changePeers(conf, done);
done.await();
assertTrue(done.getStatus().isOk() || expectedErrors.contains(done.getStatus().getRaftError()), done.getStatus().toString());
}
} catch (InterruptedException e) {
LOG.error("ChangePeersThread is interrupted", e);
}
});
}
use of org.apache.ignite.raft.jraft.closure.SynchronizedClosure in project ignite-3 by apache.
the class ItNodeTest method testReadIndexFromLearner.
@Test
public void testReadIndexFromLearner() throws Exception {
List<PeerId> peers = TestUtils.generatePeers(3);
cluster = new TestCluster("unittest", dataPath, peers, testInfo);
for (PeerId peer : peers) assertTrue(cluster.start(peer.getEndpoint(), false, 300, true));
// elect leader
cluster.waitLeader();
// get leader
Node leader = cluster.getLeader();
assertNotNull(leader);
assertEquals(3, leader.listPeers().size());
// apply tasks to leader
sendTestTaskAndWait(leader);
{
// Adds a learner
SynchronizedClosure done = new SynchronizedClosure();
PeerId learnerPeer = new PeerId(TestUtils.getLocalAddress(), TestUtils.INIT_PORT + 3);
// Start learner
assertTrue(cluster.startLearner(learnerPeer));
leader.addLearners(Arrays.asList(learnerPeer), done);
assertTrue(done.await().isOk());
assertEquals(1, leader.listAliveLearners().size());
assertEquals(1, leader.listLearners().size());
}
Thread.sleep(100);
// read from learner
Node learner = cluster.getNodes().get(3);
assertNotNull(leader);
assertReadIndex(learner, 12);
assertReadIndex(learner, 12);
}
use of org.apache.ignite.raft.jraft.closure.SynchronizedClosure in project ignite-3 by apache.
the class ItNodeTest method testChangePeersChaosWithSnapshot.
@Test
public void testChangePeersChaosWithSnapshot() throws Exception {
// start cluster
List<PeerId> peers = new ArrayList<>();
peers.add(new PeerId(TestUtils.getLocalAddress(), TestUtils.INIT_PORT));
cluster = new TestCluster("unittest", dataPath, peers, ELECTION_TIMEOUT_MILLIS, testInfo);
assertTrue(cluster.start(peers.get(0).getEndpoint(), false, 2));
// start other peers
for (int i = 1; i < 10; i++) {
PeerId peer = new PeerId(TestUtils.getLocalAddress(), TestUtils.INIT_PORT + i);
peers.add(peer);
assertTrue(cluster.start(peer.getEndpoint()));
}
ChangeArg arg = new ChangeArg(cluster, peers, false, false);
Future<?> future = startChangePeersThread(arg);
for (int i = 0; i < 5000; ) {
cluster.waitLeader();
Node leader = cluster.getLeader();
if (leader == null)
continue;
SynchronizedClosure done = new SynchronizedClosure();
Task task = new Task(ByteBuffer.wrap(("hello" + i).getBytes(UTF_8)), done);
leader.apply(task);
Status status = done.await();
if (status.isOk()) {
if (++i % 100 == 0)
System.out.println("Progress:" + i);
} else
assertEquals(RaftError.EPERM, status.getRaftError());
}
arg.stop = true;
future.get();
cluster.waitLeader();
SynchronizedClosure done = new SynchronizedClosure();
Node leader = cluster.getLeader();
leader.changePeers(new Configuration(peers), done);
Status st = done.await();
assertTrue(st.isOk(), st.getErrorMsg());
cluster.ensureSame();
assertEquals(10, cluster.getFsms().size());
for (MockStateMachine fsm : cluster.getFsms()) assertTrue(fsm.getLogs().size() >= 5000);
}
use of org.apache.ignite.raft.jraft.closure.SynchronizedClosure in project ignite-3 by apache.
the class ItNodeTest method testResetLearners.
@Test
public void testResetLearners() throws Exception {
List<PeerId> peers = TestUtils.generatePeers(3);
LinkedHashSet<PeerId> learners = new LinkedHashSet<>();
for (int i = 0; i < 3; i++) learners.add(new PeerId(TestUtils.getLocalAddress(), TestUtils.INIT_PORT + 3 + i));
cluster = new TestCluster("unittest", dataPath, peers, learners, ELECTION_TIMEOUT_MILLIS, testInfo);
for (PeerId peer : peers) assertTrue(cluster.start(peer.getEndpoint()));
for (PeerId peer : learners) assertTrue(cluster.startLearner(peer));
// elect leader
cluster.waitLeader();
Node leader = cluster.getLeader();
cluster.ensureLeader(leader);
waitForCondition(() -> leader.listAlivePeers().size() == 3, 5_000);
waitForCondition(() -> leader.listAliveLearners().size() == 3, 5_000);
sendTestTaskAndWait(leader);
List<MockStateMachine> fsms = cluster.getFsms();
assertEquals(6, fsms.size());
cluster.ensureSame();
{
// Reset learners to 2 nodes
PeerId learnerPeer = new PeerId(TestUtils.getLocalAddress(), TestUtils.INIT_PORT + 3);
learners.remove(learnerPeer);
assertEquals(2, learners.size());
SynchronizedClosure done = new SynchronizedClosure();
leader.resetLearners(new ArrayList<>(learners), done);
assertTrue(done.await().isOk());
assertEquals(2, leader.listAliveLearners().size());
assertEquals(2, leader.listLearners().size());
sendTestTaskAndWait(leader);
Thread.sleep(500);
assertEquals(6, fsms.size());
// get the removed learner's fsm
MockStateMachine fsm = fsms.remove(3);
assertEquals(fsm.getAddress(), learnerPeer.getEndpoint());
// Ensure no more logs replicated to the removed learner.
assertTrue(cluster.getLeaderFsm().getLogs().size() > fsm.getLogs().size());
assertEquals(cluster.getLeaderFsm().getLogs().size(), 2 * fsm.getLogs().size());
}
{
// remove another learner
PeerId learnerPeer = new PeerId(TestUtils.getLocalAddress(), TestUtils.INIT_PORT + 4);
SynchronizedClosure done = new SynchronizedClosure();
leader.removeLearners(Arrays.asList(learnerPeer), done);
assertTrue(done.await().isOk());
sendTestTaskAndWait(leader);
Thread.sleep(500);
// get the removed learner's fsm
MockStateMachine fsm = fsms.remove(3);
assertEquals(fsm.getAddress(), learnerPeer.getEndpoint());
// Ensure no more logs replicated to the removed learner.
assertTrue(cluster.getLeaderFsm().getLogs().size() > fsm.getLogs().size());
assertEquals(cluster.getLeaderFsm().getLogs().size(), fsm.getLogs().size() / 2 * 3);
}
assertEquals(3, leader.listAlivePeers().size());
assertEquals(1, leader.listAliveLearners().size());
assertEquals(1, leader.listLearners().size());
}
use of org.apache.ignite.raft.jraft.closure.SynchronizedClosure in project ignite-3 by apache.
the class SnapshotExecutorTest method testDoSnapshotWithIntervalDist.
@Test
public void testDoSnapshotWithIntervalDist() throws Exception {
final NodeOptions nodeOptions = new NodeOptions();
nodeOptions.setSnapshotLogIndexMargin(5);
ExecutorService testExecutor = JRaftUtils.createExecutor("test-executor", Utils.cpus());
executorService = testExecutor;
nodeOptions.setCommonExecutor(testExecutor);
Mockito.when(node.getOptions()).thenReturn(nodeOptions);
Mockito.when(fSMCaller.getLastAppliedIndex()).thenReturn(6L);
final ArgumentCaptor<SaveSnapshotClosure> saveSnapshotClosureArg = ArgumentCaptor.forClass(SaveSnapshotClosure.class);
Mockito.when(fSMCaller.onSnapshotSave(saveSnapshotClosureArg.capture())).thenReturn(true);
final SynchronizedClosure done = new SynchronizedClosure();
executor.doSnapshot(done);
final SaveSnapshotClosure closure = saveSnapshotClosureArg.getValue();
assertNotNull(closure);
closure.start(raftOptions.getRaftMessagesFactory().snapshotMeta().lastIncludedIndex(6).lastIncludedTerm(1).build());
closure.run(Status.OK());
done.await();
executor.join();
assertEquals(1, executor.getLastSnapshotTerm());
assertEquals(6, executor.getLastSnapshotIndex());
}
Aggregations