Search in sources :

Example 1 with TaskClosure

use of com.alipay.sofa.jraft.closure.TaskClosure in project sofa-jraft by sofastack.

the class NodeTest method testTripleNodes.

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

            @Override
            public void run(final 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(-1);
    assertEquals(2, cluster.getFollowers().size());
    cluster.stopAll();
}
Also used : Status(com.alipay.sofa.jraft.Status) Task(com.alipay.sofa.jraft.entity.Task) Node(com.alipay.sofa.jraft.Node) CountDownLatch(java.util.concurrent.CountDownLatch) ByteBuffer(java.nio.ByteBuffer) Vector(java.util.Vector) PeerId(com.alipay.sofa.jraft.entity.PeerId) TaskClosure(com.alipay.sofa.jraft.closure.TaskClosure) Test(org.junit.Test)

Example 2 with TaskClosure

use of com.alipay.sofa.jraft.closure.TaskClosure in project sofa-jraft by sofastack.

the class NodeTest method testTripleNodesV1V2Codec.

@Test
public void testTripleNodesV1V2Codec() throws Exception {
    final List<PeerId> peers = TestUtils.generatePeers(3);
    final TestCluster cluster = new TestCluster("unittest", this.dataPath, peers);
    for (int i = 0; i < peers.size(); i++) {
        // Peer3 use codec v1
        if (i == 2) {
            cluster.setRaftServiceFactory(new V1JRaftServiceFactory());
        }
        assertTrue(cluster.start(peers.get(i).getEndpoint()));
    }
    // elect leader
    cluster.waitLeader();
    // get leader
    Node leader = cluster.getLeader();
    assertNotNull(leader);
    assertEquals(3, leader.listPeers().size());
    // apply tasks to leader
    this.sendTestTaskAndWait(leader);
    {
        final ByteBuffer data = ByteBuffer.wrap("no closure".getBytes());
        final Task task = new Task(data, null);
        leader.apply(task);
    }
    {
        // task with TaskClosure
        final ByteBuffer data = ByteBuffer.wrap("task closure".getBytes());
        final Vector<String> cbs = new Vector<>();
        final CountDownLatch latch = new CountDownLatch(1);
        final Task task = new Task(data, new TaskClosure() {

            @Override
            public void run(final 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(-1);
    assertEquals(2, cluster.getFollowers().size());
    // transfer the leader to v1 codec peer
    assertTrue(leader.transferLeadershipTo(peers.get(2)).isOk());
    cluster.waitLeader();
    leader = cluster.getLeader();
    assertNotNull(leader);
    assertEquals(leader.getLeaderId(), peers.get(2));
    // apply tasks to leader
    this.sendTestTaskAndWait(leader);
    cluster.ensureSame();
    cluster.stopAll();
    // start the cluster with v2 codec, should work
    final TestCluster newCluster = new TestCluster("unittest", this.dataPath, peers);
    for (int i = 0; i < peers.size(); i++) {
        assertTrue(newCluster.start(peers.get(i).getEndpoint()));
    }
    // elect leader
    newCluster.waitLeader();
    newCluster.ensureSame();
    leader = newCluster.getLeader();
    assertNotNull(leader);
    // apply new tasks
    this.sendTestTaskAndWait(leader);
    newCluster.ensureSame();
    newCluster.stopAll();
}
Also used : Status(com.alipay.sofa.jraft.Status) Task(com.alipay.sofa.jraft.entity.Task) Node(com.alipay.sofa.jraft.Node) CountDownLatch(java.util.concurrent.CountDownLatch) ByteBuffer(java.nio.ByteBuffer) Endpoint(com.alipay.sofa.jraft.util.Endpoint) TaskClosure(com.alipay.sofa.jraft.closure.TaskClosure) Vector(java.util.Vector) PeerId(com.alipay.sofa.jraft.entity.PeerId) Test(org.junit.Test)

Example 3 with TaskClosure

use of com.alipay.sofa.jraft.closure.TaskClosure in project sofa-jraft by sofastack.

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);
        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 : LoadSnapshotClosure(com.alipay.sofa.jraft.closure.LoadSnapshotClosure) Closure(com.alipay.sofa.jraft.Closure) SaveSnapshotClosure(com.alipay.sofa.jraft.closure.SaveSnapshotClosure) TaskClosure(com.alipay.sofa.jraft.closure.TaskClosure) Configuration(com.alipay.sofa.jraft.conf.Configuration) ArrayList(java.util.ArrayList) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) LogId(com.alipay.sofa.jraft.entity.LogId) LogEntry(com.alipay.sofa.jraft.entity.LogEntry) TaskClosure(com.alipay.sofa.jraft.closure.TaskClosure)

Example 4 with TaskClosure

use of com.alipay.sofa.jraft.closure.TaskClosure in project sofa-jraft by sofastack.

the class NodeTest method testTripleNodesWithLearners.

@Test
public void testTripleNodesWithLearners() throws Exception {
    final List<PeerId> peers = TestUtils.generatePeers(3);
    final TestCluster cluster = new TestCluster("unittest", this.dataPath, peers);
    for (final PeerId peer : peers) {
        assertTrue(cluster.start(peer.getEndpoint()));
    }
    // elect leader
    cluster.waitLeader();
    // get leader
    final Node leader = cluster.getLeader();
    assertNotNull(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.getMyIp(), 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
    this.sendTestTaskAndWait(leader);
    {
        final ByteBuffer data = ByteBuffer.wrap("no closure".getBytes());
        final Task task = new Task(data, null);
        leader.apply(task);
    }
    {
        // task with TaskClosure
        final ByteBuffer data = ByteBuffer.wrap("task closure".getBytes());
        final Vector<String> cbs = new Vector<>();
        final CountDownLatch latch = new CountDownLatch(1);
        final Task task = new Task(data, new TaskClosure() {

            @Override
            public void run(final 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(-1);
    {
        // Adds another learner
        SynchronizedClosure done = new SynchronizedClosure();
        PeerId learnerPeer = new PeerId(TestUtils.getMyIp(), 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());
    }
    {
        // stop two followers
        for (Node follower : cluster.getFollowers()) {
            assertTrue(cluster.stop(follower.getNodeId().getPeerId().getEndpoint()));
        }
        // send a new task
        final ByteBuffer data = ByteBuffer.wrap("task closure".getBytes());
        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());
        cluster.ensureSame(-1);
    }
    cluster.stopAll();
}
Also used : Status(com.alipay.sofa.jraft.Status) SynchronizedClosure(com.alipay.sofa.jraft.closure.SynchronizedClosure) Task(com.alipay.sofa.jraft.entity.Task) Node(com.alipay.sofa.jraft.Node) CountDownLatch(java.util.concurrent.CountDownLatch) ByteBuffer(java.nio.ByteBuffer) Vector(java.util.Vector) PeerId(com.alipay.sofa.jraft.entity.PeerId) TaskClosure(com.alipay.sofa.jraft.closure.TaskClosure) Test(org.junit.Test)

Example 5 with TaskClosure

use of com.alipay.sofa.jraft.closure.TaskClosure in project sofa-jraft by sofastack.

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(com.alipay.sofa.jraft.closure.TaskClosure)

Aggregations

TaskClosure (com.alipay.sofa.jraft.closure.TaskClosure)5 Node (com.alipay.sofa.jraft.Node)3 Status (com.alipay.sofa.jraft.Status)3 PeerId (com.alipay.sofa.jraft.entity.PeerId)3 Task (com.alipay.sofa.jraft.entity.Task)3 ByteBuffer (java.nio.ByteBuffer)3 Vector (java.util.Vector)3 CountDownLatch (java.util.concurrent.CountDownLatch)3 Test (org.junit.Test)3 Closure (com.alipay.sofa.jraft.Closure)1 LoadSnapshotClosure (com.alipay.sofa.jraft.closure.LoadSnapshotClosure)1 SaveSnapshotClosure (com.alipay.sofa.jraft.closure.SaveSnapshotClosure)1 SynchronizedClosure (com.alipay.sofa.jraft.closure.SynchronizedClosure)1 Configuration (com.alipay.sofa.jraft.conf.Configuration)1 LogEntry (com.alipay.sofa.jraft.entity.LogEntry)1 LogId (com.alipay.sofa.jraft.entity.LogId)1 Endpoint (com.alipay.sofa.jraft.util.Endpoint)1 ArrayList (java.util.ArrayList)1 CopyOnWriteArrayList (java.util.concurrent.CopyOnWriteArrayList)1