raft: rename storage to persistence

The new naming scheme more clearly communicates to the client of
the raft library that the `persistence` interface implements
persistency layer of the fsm that is powering the raft
protocol itself rather than the client-side workflow and
user-provided `state_machine`.

Signed-off-by: Pavel Solodovnikov <pa.solodovnikov@scylladb.com>
Message-Id: <20201126135114.7933-1-pa.solodovnikov@scylladb.com>
This commit is contained in:
Pavel Solodovnikov
2020-11-26 16:51:14 +03:00
committed by Avi Kivity
parent 248449816b
commit 041072b59f
6 changed files with 35 additions and 35 deletions

View File

@@ -17,7 +17,7 @@ For more details about Raft see https://raft.github.io/
-----
In order to use the library the application has to provide implementations
for RPC, storage and state machine APIs, defined in raft/raft.hh. The
for RPC, persistence and state machine APIs, defined in raft/raft.hh. The
purpose of these interfaces is:
- provide a way to communicate between Raft protocol instances
- persist the required protocol state on disk,
@@ -32,7 +32,7 @@ of the Raft consistency protocol on its environment:
in which messages can be lost, reordered, retransmitted more than
once, but not corrupted. Specifically, it's an error to
deliver a message to a Raft server which was not sent to it.
- storage should provide a durable persistent storage, which
- persistence should provide a durable persistent storage, which
survives between state machine restarts and does not corrupt
its state.
- Raft library calls `state_machine::apply_entry()` for entries
@@ -54,7 +54,7 @@ is not supported.
For an example of first usage see `replication_test.cc` in test/raft/.
In a nutshell:
- create instances of RPC, storage, and state machine
- create instances of RPC, persistence, and state machine
- pass them to an instance of Raft server - the facade to the Raft cluster
on this node
- repeat the above for every node in the cluster
@@ -64,8 +64,8 @@ In a nutshell:
### Subsequent usages
Similar to the first usage, but `storage::load_term_and_vote()`
`storage::load_log()`, `storage::load_snapshot()` are expected to
Similar to the first usage, but `persistence::load_term_and_vote()`
`persistence::load_log()`, `persistence::load_snapshot()` are expected to
return valid protocol state as persisted by the previous incarnation
of an instance of class server.

View File

@@ -108,7 +108,7 @@ class fsm {
server_id _current_leader;
// What state the server is in. The default is follower.
std::variant<follower, candidate, leader> _state;
// _current_term, _voted_for && _log are persisted in storage
// _current_term, _voted_for && _log are persisted in persistence
// The latest term the server has seen.
term_t _current_term;
// Candidate id that received a vote in the current term (or

View File

@@ -212,11 +212,11 @@ using rpc_message = std::variant<append_request_send, append_reply, vote_request
// std::deque move constructor is not nothrow hence cannot be used
using log_entries = boost::container::deque<log_entry_ptr>;
// rpc, storage and satte_machine classes will have to be implemented by the
// rpc, persistence and state_machine classes will have to be implemented by the
// raft user to provide network, persistency and busyness logic support
// repectively.
class rpc;
class storage;
class persistence;
// Any of the functions may return an error, but it will kill the
// raft instance that uses it. Depending on what state the failure
@@ -341,15 +341,15 @@ public:
void set_rpc_server(class rpc *rpc) { rpc->_client = this; }
};
// This class represents persistent storage state. If any of the
// This class represents persistent storage state for the internal fsm. If any of the
// function returns an error the Raft instance will be aborted.
class storage {
class persistence {
public:
virtual ~storage() {}
virtual ~persistence() {}
// Persist given term and vote.
// Can be called concurrently with other save-* functions in
// the storage and with itself but an implementation has to
// the persistence and with itself but an implementation has to
// make sure that the result is returned back in the calling order.
virtual future<> store_term_and_vote(term_t term, server_id vote) = 0;
@@ -395,8 +395,8 @@ public:
// entries.
virtual future<> truncate_log(index_t idx) = 0;
// Stop the storage instance by aborting the work that can be
// aborted and waiting for all the rest to complete any
// Stop the persistence instance by aborting the work that can be
// aborted and waiting for all the rest to complete. Any
// unfinished store/load operation may return an error after
// this function is called.
virtual future<> abort() = 0;

View File

@@ -40,7 +40,7 @@ namespace raft {
class server_impl : public rpc_server, public server {
public:
explicit server_impl(server_id uuid, std::unique_ptr<rpc> rpc,
std::unique_ptr<state_machine> state_machine, std::unique_ptr<storage> storage,
std::unique_ptr<state_machine> state_machine, std::unique_ptr<persistence> persistence,
seastar::shared_ptr<failure_detector> failure_detector, server::configuration config);
server_impl(server_impl&&) = delete;
@@ -69,7 +69,7 @@ public:
private:
std::unique_ptr<rpc> _rpc;
std::unique_ptr<state_machine> _state_machine;
std::unique_ptr<storage> _storage;
std::unique_ptr<persistence> _persistence;
seastar::shared_ptr<failure_detector> _failure_detector;
// Protocol deterministic finite-state machine
std::unique_ptr<fsm> _fsm;
@@ -141,10 +141,10 @@ private:
};
server_impl::server_impl(server_id uuid, std::unique_ptr<rpc> rpc,
std::unique_ptr<state_machine> state_machine, std::unique_ptr<storage> storage,
std::unique_ptr<state_machine> state_machine, std::unique_ptr<persistence> persistence,
seastar::shared_ptr<failure_detector> failure_detector, server::configuration config) :
_rpc(std::move(rpc)), _state_machine(std::move(state_machine)),
_storage(std::move(storage)), _failure_detector(failure_detector),
_persistence(std::move(persistence)), _failure_detector(failure_detector),
_id(uuid), _config(config) {
set_rpc_server(_rpc.get());
if (_config.snapshot_threshold > _config.max_log_length) {
@@ -153,10 +153,10 @@ server_impl::server_impl(server_id uuid, std::unique_ptr<rpc> rpc,
}
future<> server_impl::start() {
auto [term, vote] = co_await _storage->load_term_and_vote();
auto snapshot = co_await _storage->load_snapshot();
auto [term, vote] = co_await _persistence->load_term_and_vote();
auto snapshot = co_await _persistence->load_snapshot();
auto snp_id = snapshot.id;
auto log_entries = co_await _storage->load_log();
auto log_entries = co_await _persistence->load_log();
auto log = raft::log(std::move(snapshot), std::move(log_entries));
index_t stable_idx = log.stable_idx();
_fsm = std::make_unique<fsm>(_id, term, vote, std::move(log), *_failure_detector,
@@ -305,13 +305,13 @@ future<> server_impl::io_fiber(index_t last_stable) {
// together. A vote may change independently of
// term, but it's safe to update both in this
// case.
co_await _storage->store_term_and_vote(batch.term, batch.vote);
co_await _persistence->store_term_and_vote(batch.term, batch.vote);
}
if (batch.snp) {
logger.trace("[{}] io_fiber storing snapshot {}", _id, batch.snp->id);
// Persist the snapshot
co_await _storage->store_snapshot(*batch.snp, _config.snapshot_trailing);
co_await _persistence->store_snapshot(*batch.snp, _config.snapshot_trailing);
// If this is locally generated snapshot there is no need to
// load it.
if (_last_loaded_snapshot_id != batch.snp->id) {
@@ -328,12 +328,12 @@ future<> server_impl::io_fiber(index_t last_stable) {
auto& entries = batch.log_entries;
if (last_stable >= entries[0]->idx) {
co_await _storage->truncate_log(entries[0]->idx);
co_await _persistence->truncate_log(entries[0]->idx);
}
// Combine saving and truncating into one call?
// will require storage to keep track of last idx
co_await _storage->store_log_entries(entries);
// will require persistence to keep track of last idx
co_await _persistence->store_log_entries(entries);
last_stable = (*entries.crbegin())->idx;
}
@@ -471,7 +471,7 @@ future<> server_impl::abort() {
auto snapshots = seastar::when_all_succeed(snp_futures.begin(), snp_futures.end());
return seastar::when_all_succeed(std::move(_io_status), std::move(_applier_status),
_rpc->abort(), _state_machine->abort(), _storage->abort(), std::move(snapshots)).discard_result();
_rpc->abort(), _state_machine->abort(), _persistence->abort(), std::move(snapshots)).discard_result();
}
future<> server_impl::add_server(server_id id, bytes node_info, clock_type::duration timeout) {
@@ -511,11 +511,11 @@ void server_impl::tick() {
}
std::unique_ptr<server> create_server(server_id uuid, std::unique_ptr<rpc> rpc,
std::unique_ptr<state_machine> state_machine, std::unique_ptr<storage> storage,
std::unique_ptr<state_machine> state_machine, std::unique_ptr<persistence> persistence,
seastar::shared_ptr<failure_detector> failure_detector, server::configuration config) {
assert(uuid != raft::server_id{utils::UUID(0, 0)});
return std::make_unique<raft::server_impl>(uuid, std::move(rpc), std::move(state_machine),
std::move(storage), failure_detector, config);
std::move(persistence), failure_detector, config);
}
std::ostream& operator<<(std::ostream& os, const server_impl& s) {

View File

@@ -128,7 +128,7 @@ public:
};
std::unique_ptr<server> create_server(server_id uuid, std::unique_ptr<rpc> rpc,
std::unique_ptr<state_machine> state_machine, std::unique_ptr<storage> storage,
std::unique_ptr<state_machine> state_machine, std::unique_ptr<persistence> persistence,
seastar::shared_ptr<failure_detector> failure_detector, server::configuration config);
} // namespace raft

View File

@@ -202,12 +202,12 @@ struct initial_state {
raft::server::configuration server_config = raft::server::configuration{.append_request_threshold = 200};
};
class storage : public raft::storage {
class persistence : public raft::persistence {
raft::server_id _id;
initial_state _conf;
public:
storage(raft::server_id id, initial_state conf) : _id(id), _conf(std::move(conf)) {}
storage() {}
persistence(raft::server_id id, initial_state conf) : _id(id), _conf(std::move(conf)) {}
persistence() {}
virtual future<> store_term_and_vote(raft::term_t term, raft::server_id vote) { return seastar::sleep(1us); }
virtual future<std::pair<raft::term_t, raft::server_id>> load_term_and_vote() {
auto term_and_vote = std::make_pair(_conf.term, _conf.vote);
@@ -319,10 +319,10 @@ create_raft_server(raft::server_id uuid, state_machine::apply_fn apply, initial_
auto sm = std::make_unique<state_machine>(uuid, std::move(apply), std::move(val), apply_entries);
auto& rsm = *sm;
auto mrpc = std::make_unique<rpc>(uuid);
auto mstorage = std::make_unique<storage>(uuid, state);
auto mpersistence = std::make_unique<persistence>(uuid, state);
auto fd = seastar::make_shared<failure_detector>(uuid);
auto raft = raft::create_server(uuid, std::move(mrpc), std::move(sm), std::move(mstorage),
auto raft = raft::create_server(uuid, std::move(mrpc), std::move(sm), std::move(mpersistence),
std::move(fd), state.server_config);
return std::make_pair(std::move(raft), &rsm);