Search in sources :

Example 1 with TaskClosure

use of org.apache.ignite.raft.jraft.closure.TaskClosure in project ignite-3 by apache.

the class FSMCallerImpl method onTaskCommitted.

private void onTaskCommitted(final List<TaskClosure> closures) {
    for (int i = 0, size = closures.size(); i < size; i++) {
        final TaskClosure done = closures.get(i);
        done.onCommitted();
    }
}
Also used : TaskClosure(org.apache.ignite.raft.jraft.closure.TaskClosure)

Example 2 with TaskClosure

use of org.apache.ignite.raft.jraft.closure.TaskClosure in project ignite-3 by apache.

the class FSMCallerImpl method doCommitted.

private void doCommitted(final long committedIndex) {
    if (!this.error.getStatus().isOk()) {
        return;
    }
    final long lastAppliedIndex = this.lastAppliedIndex.get();
    // We can tolerate the disorder of committed_index
    if (lastAppliedIndex >= committedIndex) {
        return;
    }
    final long startMs = Utils.monotonicMs();
    try {
        final List<Closure> closures = new ArrayList<>();
        final List<TaskClosure> taskClosures = new ArrayList<>();
        final long firstClosureIndex = this.closureQueue.popClosureUntil(committedIndex, closures, taskClosures);
        // Calls TaskClosure#onCommitted if necessary
        onTaskCommitted(taskClosures);
        Requires.requireTrue(firstClosureIndex >= 0, "Invalid firstClosureIndex");
        final IteratorImpl iterImpl = new IteratorImpl(this.fsm, this.logManager, closures, firstClosureIndex, lastAppliedIndex, committedIndex, this.applyingIndex, this.node.getOptions());
        while (iterImpl.isGood()) {
            final LogEntry logEntry = iterImpl.entry();
            if (logEntry.getType() != EnumOutter.EntryType.ENTRY_TYPE_DATA) {
                if (logEntry.getType() == EnumOutter.EntryType.ENTRY_TYPE_CONFIGURATION) {
                    if (logEntry.getOldPeers() != null && !logEntry.getOldPeers().isEmpty()) {
                        // Joint stage is not supposed to be noticeable by end users.
                        this.fsm.onConfigurationCommitted(new Configuration(iterImpl.entry().getPeers()));
                    }
                }
                if (iterImpl.done() != null) {
                    // For other entries, we have nothing to do besides flush the
                    // pending tasks and run this closure to notify the caller that the
                    // entries before this one were successfully committed and applied.
                    iterImpl.done().run(Status.OK());
                }
                iterImpl.next();
                continue;
            }
            // Apply data task to user state machine
            doApplyTasks(iterImpl);
        }
        if (iterImpl.hasError()) {
            setError(iterImpl.getError());
            iterImpl.runTheRestClosureWithError();
        }
        final long lastIndex = iterImpl.getIndex() - 1;
        final long lastTerm = this.logManager.getTerm(lastIndex);
        final LogId lastAppliedId = new LogId(lastIndex, lastTerm);
        this.lastAppliedIndex.set(lastIndex);
        this.lastAppliedTerm = lastTerm;
        this.logManager.setAppliedId(lastAppliedId);
        notifyLastAppliedIndexUpdated(lastIndex);
    } finally {
        this.nodeMetrics.recordLatency("fsm-commit", Utils.monotonicMs() - startMs);
    }
}
Also used : TaskClosure(org.apache.ignite.raft.jraft.closure.TaskClosure) SaveSnapshotClosure(org.apache.ignite.raft.jraft.closure.SaveSnapshotClosure) Closure(org.apache.ignite.raft.jraft.Closure) LoadSnapshotClosure(org.apache.ignite.raft.jraft.closure.LoadSnapshotClosure) Configuration(org.apache.ignite.raft.jraft.conf.Configuration) ArrayList(java.util.ArrayList) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) LogId(org.apache.ignite.raft.jraft.entity.LogId) LogEntry(org.apache.ignite.raft.jraft.entity.LogEntry) TaskClosure(org.apache.ignite.raft.jraft.closure.TaskClosure)

Example 3 with TaskClosure

use of org.apache.ignite.raft.jraft.closure.TaskClosure in project ignite-3 by apache.

the class ItNodeTest method testTripleNodesWithLearners.

@Test
public void testTripleNodesWithLearners() throws Exception {
    List<PeerId> peers = TestUtils.generatePeers(3);
    cluster = new TestCluster("unittest", dataPath, peers, testInfo);
    for (PeerId peer : peers) assertTrue(cluster.start(peer.getEndpoint()));
    // elect leader
    cluster.waitLeader();
    // get leader
    Node leader = cluster.getLeader();
    assertNotNull(leader);
    cluster.ensureLeader(leader);
    assertEquals(3, leader.listPeers().size());
    assertTrue(leader.listLearners().isEmpty());
    assertTrue(leader.listAliveLearners().isEmpty());
    {
        // 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());
    }
    // apply tasks to leader
    sendTestTaskAndWait(leader);
    {
        ByteBuffer data = ByteBuffer.wrap("no closure".getBytes(UTF_8));
        Task task = new Task(data, null);
        leader.apply(task);
    }
    {
        // task with TaskClosure
        ByteBuffer data = ByteBuffer.wrap("task closure".getBytes(UTF_8));
        List<String> cbs = synchronizedList(new ArrayList<>());
        CountDownLatch latch = new CountDownLatch(1);
        Task task = new Task(data, new TaskClosure() {

            @Override
            public void run(Status status) {
                cbs.add("apply");
                latch.countDown();
            }

            @Override
            public void onCommitted() {
                cbs.add("commit");
            }
        });
        leader.apply(task);
        latch.await();
        assertEquals(2, cbs.size());
        assertEquals("commit", cbs.get(0));
        assertEquals("apply", cbs.get(1));
    }
    assertEquals(4, cluster.getFsms().size());
    assertEquals(2, cluster.getFollowers().size());
    assertEquals(1, cluster.getLearners().size());
    cluster.ensureSame();
    {
        // Adds another learner
        SynchronizedClosure done = new SynchronizedClosure();
        PeerId learnerPeer = new PeerId(TestUtils.getLocalAddress(), TestUtils.INIT_PORT + 4);
        // Start learner
        assertTrue(cluster.startLearner(learnerPeer));
        leader.addLearners(Arrays.asList(learnerPeer), done);
        assertTrue(done.await().isOk());
        assertEquals(2, leader.listAliveLearners().size());
        assertEquals(2, leader.listLearners().size());
        cluster.ensureSame();
    }
    {
        // stop two followers
        for (Node follower : cluster.getFollowers()) assertTrue(cluster.stop(follower.getNodeId().getPeerId().getEndpoint()));
        // send a new task
        ByteBuffer data = ByteBuffer.wrap("task closure".getBytes(UTF_8));
        SynchronizedClosure done = new SynchronizedClosure();
        leader.apply(new Task(data, done));
        // should fail
        assertFalse(done.await().isOk());
        assertEquals(RaftError.EPERM, done.getStatus().getRaftError());
        // One peer with two learners.
        assertEquals(3, cluster.getFsms().size());
    }
}
Also used : Status(org.apache.ignite.raft.jraft.Status) SynchronizedClosure(org.apache.ignite.raft.jraft.closure.SynchronizedClosure) Task(org.apache.ignite.raft.jraft.entity.Task) Node(org.apache.ignite.raft.jraft.Node) ArrayList(java.util.ArrayList) Collections.synchronizedList(java.util.Collections.synchronizedList) ArrayList(java.util.ArrayList) List(java.util.List) Collectors.toList(java.util.stream.Collectors.toList) CountDownLatch(java.util.concurrent.CountDownLatch) ByteBuffer(java.nio.ByteBuffer) PeerId(org.apache.ignite.raft.jraft.entity.PeerId) TaskClosure(org.apache.ignite.raft.jraft.closure.TaskClosure) Test(org.junit.jupiter.api.Test)

Example 4 with TaskClosure

use of org.apache.ignite.raft.jraft.closure.TaskClosure in project ignite-3 by apache.

the class ItNodeTest method testTripleNodes.

@Test
public void testTripleNodes() throws Exception {
    List<PeerId> peers = TestUtils.generatePeers(3);
    cluster = new TestCluster("unittest", dataPath, peers, testInfo);
    for (PeerId peer : peers) assertTrue(cluster.start(peer.getEndpoint()));
    // elect leader
    cluster.waitLeader();
    // get leader
    Node leader = cluster.getLeader();
    assertNotNull(leader);
    cluster.ensureLeader(leader);
    assertEquals(3, leader.listPeers().size());
    // apply tasks to leader
    sendTestTaskAndWait(leader);
    {
        ByteBuffer data = ByteBuffer.wrap("no closure".getBytes(UTF_8));
        Task task = new Task(data, null);
        leader.apply(task);
    }
    {
        // task with TaskClosure
        ByteBuffer data = ByteBuffer.wrap("task closure".getBytes(UTF_8));
        List<String> cbs = synchronizedList(new ArrayList<>());
        CountDownLatch latch = new CountDownLatch(1);
        Task task = new Task(data, new TaskClosure() {

            @Override
            public void run(Status status) {
                cbs.add("apply");
                latch.countDown();
            }

            @Override
            public void onCommitted() {
                cbs.add("commit");
            }
        });
        leader.apply(task);
        latch.await();
        assertEquals(2, cbs.size());
        assertEquals("commit", cbs.get(0));
        assertEquals("apply", cbs.get(1));
    }
    cluster.ensureSame();
    assertEquals(2, cluster.getFollowers().size());
}
Also used : Status(org.apache.ignite.raft.jraft.Status) Task(org.apache.ignite.raft.jraft.entity.Task) Node(org.apache.ignite.raft.jraft.Node) ArrayList(java.util.ArrayList) Collections.synchronizedList(java.util.Collections.synchronizedList) ArrayList(java.util.ArrayList) List(java.util.List) Collectors.toList(java.util.stream.Collectors.toList) CountDownLatch(java.util.concurrent.CountDownLatch) ByteBuffer(java.nio.ByteBuffer) PeerId(org.apache.ignite.raft.jraft.entity.PeerId) TaskClosure(org.apache.ignite.raft.jraft.closure.TaskClosure) Test(org.junit.jupiter.api.Test)

Aggregations

TaskClosure (org.apache.ignite.raft.jraft.closure.TaskClosure)4 ArrayList (java.util.ArrayList)3 ByteBuffer (java.nio.ByteBuffer)2 Collections.synchronizedList (java.util.Collections.synchronizedList)2 List (java.util.List)2 CountDownLatch (java.util.concurrent.CountDownLatch)2 Collectors.toList (java.util.stream.Collectors.toList)2 Node (org.apache.ignite.raft.jraft.Node)2 Status (org.apache.ignite.raft.jraft.Status)2 PeerId (org.apache.ignite.raft.jraft.entity.PeerId)2 Task (org.apache.ignite.raft.jraft.entity.Task)2 Test (org.junit.jupiter.api.Test)2 CopyOnWriteArrayList (java.util.concurrent.CopyOnWriteArrayList)1 Closure (org.apache.ignite.raft.jraft.Closure)1 LoadSnapshotClosure (org.apache.ignite.raft.jraft.closure.LoadSnapshotClosure)1 SaveSnapshotClosure (org.apache.ignite.raft.jraft.closure.SaveSnapshotClosure)1 SynchronizedClosure (org.apache.ignite.raft.jraft.closure.SynchronizedClosure)1 Configuration (org.apache.ignite.raft.jraft.conf.Configuration)1 LogEntry (org.apache.ignite.raft.jraft.entity.LogEntry)1 LogId (org.apache.ignite.raft.jraft.entity.LogId)1