An industrial-grade C++ implementation of RAFT consensus algorithm based on brpc, widely used inside Baidu to build highly-available distributed systems.
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是不确定的。
这里有其他逻辑保护吗?