Changed RaftCore API; giving up Leader status if the leader cannot write its log

This commit is contained in:
Pavel Kirienko
2015-05-10 23:44:25 +03:00
parent a6b0a256fb
commit 731d9f4574
3 changed files with 13 additions and 22 deletions
@@ -812,10 +812,10 @@ public:
/** /**
* Inserts one entry into log. * Inserts one entry into log.
* Failures are tolerble because all operations are idempotent.
* This method will trigger an assertion failure and return error if the current node is not the leader. * This method will trigger an assertion failure and return error if the current node is not the leader.
* If operation fails, the node may give up its Leader status.
*/ */
int appendLog(const Entry::FieldTypes::unique_id& unique_id, NodeID node_id) void appendLog(const Entry::FieldTypes::unique_id& unique_id, NodeID node_id)
{ {
if (isLeader()) if (isLeader())
{ {
@@ -825,12 +825,15 @@ public:
entry.term = persistent_state_.getCurrentTerm(); entry.term = persistent_state_.getCurrentTerm();
trace(TraceRaftNewLogEntry, entry.node_id); trace(TraceRaftNewLogEntry, entry.node_id);
return persistent_state_.getLog().append(entry); const int res = persistent_state_.getLog().append(entry);
if (res < 0)
{
handlePersistentStateUpdateError(res);
}
} }
else else
{ {
UAVCAN_ASSERT(0); UAVCAN_ASSERT(0);
return -ErrLogic;
} }
} }
@@ -853,8 +856,8 @@ public:
* Predicate is a callable of the following prototype: * Predicate is a callable of the following prototype:
* bool (const LogEntryInfo& entry) * bool (const LogEntryInfo& entry)
* Once the predicate returns true, the loop will be terminated and the method will return an initialized lazy * Once the predicate returns true, the loop will be terminated and the method will return an initialized lazy
* contructor to the last visited entry; otherwise the constructor will not be initialized. In this case, lazy * contructor with the last visited entry; otherwise the constructor will not be initialized.
* constructor is used as boost::optional. * In this case, lazy constructor is used as boost::optional.
* The log is always traversed from HIGH to LOW index values, i.e. entry 0 will be traversed last. * The log is always traversed from HIGH to LOW index values, i.e. entry 0 will be traversed last.
*/ */
template <typename Predicate> template <typename Predicate>
@@ -169,11 +169,7 @@ class Server : IAllocationRequestHandler
if (raft_core_.isLeader()) if (raft_core_.isLeader())
{ {
const int res = raft_core_.appendLog(uid, node_id); raft_core_.appendLog(uid, node_id);
if (res < 0)
{
node_.registerInternalFailure("Raft log append discovered node");
}
} }
} }
@@ -200,11 +196,7 @@ class Server : IAllocationRequestHandler
if (!result.isConstructed()) if (!result.isConstructed())
{ {
const int res = raft_core_.appendLog(own_unique_id_, node_.getNodeID()); raft_core_.appendLog(own_unique_id_, node_.getNodeID());
if (res < 0)
{
node_.registerInternalFailure("Raft log append with self ID");
}
} }
} }
@@ -230,11 +222,7 @@ class Server : IAllocationRequestHandler
UAVCAN_TRACE("dynamic_node_id_server::distributed::Server", "New node ID allocated: %d", UAVCAN_TRACE("dynamic_node_id_server::distributed::Server", "New node ID allocated: %d",
int(allocated_node_id.get())); int(allocated_node_id.get()));
const int res = raft_core_.appendLog(unique_id, allocated_node_id); raft_core_.appendLog(unique_id, allocated_node_id);
if (res < 0)
{
node_.registerInternalFailure("Raft log append new allocation");
}
} }
void tryPublishAllocationResult(const protocol::dynamic_node_id::server::Entry& entry) void tryPublishAllocationResult(const protocol::dynamic_node_id::server::Entry& entry)
@@ -83,7 +83,7 @@ TEST(DynamicNodeIDServer, RaftCoreBasic)
Entry::FieldTypes::unique_id unique_id; Entry::FieldTypes::unique_id unique_id;
uavcan::fill_n(unique_id.begin(), 16, uint8_t(0xAA)); uavcan::fill_n(unique_id.begin(), 16, uint8_t(0xAA));
ASSERT_LE(0, raft_a->appendLog(unique_id, uavcan::NodeID(1))); raft_a->appendLog(unique_id, uavcan::NodeID(1));
nodes.spinBoth(uavcan::MonotonicDuration::fromMSec(2000)); nodes.spinBoth(uavcan::MonotonicDuration::fromMSec(2000));