baidu / braft

An industrial-grade C++ implementation of RAFT consensus algorithm based on brpc, widely used inside Baidu to build highly-available distributed systems.
Apache License 2.0
3.86k stars 865 forks source link

FSMCaller::do_committed时不会出现乱序apply吗? #395

Open cangfengzhs opened 1 year ago

cangfengzhs commented 1 year ago
void FSMCaller::do_committed(int64_t committed_index) {
    if (!_error.status().ok()) {
        return;
    }
    int64_t last_applied_index = _last_applied_index.load(
                                        butil::memory_order_relaxed);

    // We can tolerate the disorder of committed_index
    if (last_applied_index >= committed_index) {
        return;
    }
    std::vector<Closure*> closure;
    int64_t first_closure_index = 0;
    CHECK_EQ(0, _closure_queue->pop_closure_until(committed_index, &closure,           // A
                                                  &first_closure_index));

    IteratorImpl iter_impl(_fsm, _log_manager, &closure, first_closure_index,
                 last_applied_index, committed_index, &_applying_index);
    for (; iter_impl.is_good();) {
       ...
        Iterator iter(&iter_impl);
        _fsm->on_apply(iter);    // B
        LOG_IF(ERROR, iter.valid())
                << "Node " << _node->node_id() 
                << " Iterator is still valid, did you return before iterator "
                   " reached the end?";
        // Try move to next in case that we pass the same log twice.
        iter.next();
    }

do_committed是不加锁的,也就是说这个函数可以并发执行。在pop_closure_until中会加锁把执行的closure拿到。但是之后在_fsm->on_apply(iter)时,如果存在并发,那么是哪个Log先被apply是不确定的。

这里有其他逻辑保护吗?

PFZheng commented 1 year ago

不会出现乱序,execq 是无锁队列,保序的