1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
|
#ifndef CERT_TRANS_LOG_STRICT_CONSISTENT_STORE_H_
#define CERT_TRANS_LOG_STRICT_CONSISTENT_STORE_H_
#include "log/consistent_store.h"
#include "log/logged_entry.h"
#include "util/masterelection.h"
namespace cert_trans {
// A wrapper around a ConsistentStore which will not allow changes to
// the cluster state which should only be performed by the current master
// unless this node /is/ the current master.
//
// Note that while this is better than just gating the start of a high-level
// action (especially a long running action, e.g. a signing run) with a check
// to IsMaster(), it is still necessarily racy because etcd doesn't support
// atomic updates across keys.)
class StrictConsistentStore : public ConsistentStore {
public:
// Takes ownership of |peer|, but not |election|
StrictConsistentStore(const MasterElection* election, ConsistentStore* peer);
virtual ~StrictConsistentStore() = default;
// Methods requiring that the caller is currently master:
util::StatusOr<int64_t> NextAvailableSequenceNumber() const override;
util::Status SetServingSTH(const ct::SignedTreeHead& new_sth) override;
util::Status UpdateSequenceMapping(
EntryHandle<ct::SequenceMapping>* entry) override;
util::Status SetClusterConfig(const ct::ClusterConfig& config) override;
util::StatusOr<int64_t> CleanupOldEntries() override;
// Other methods:
util::StatusOr<ct::SignedTreeHead> GetServingSTH() const override {
return peer_->GetServingSTH();
}
util::Status AddPendingEntry(LoggedEntry* entry) override {
return peer_->AddPendingEntry(entry);
}
util::Status GetPendingEntryForHash(
const std::string& hash,
EntryHandle<LoggedEntry>* entry) const override {
return peer_->GetPendingEntryForHash(hash, entry);
}
util::Status GetPendingEntries(
std::vector<EntryHandle<LoggedEntry>>* entries) const override {
return peer_->GetPendingEntries(entries);
}
util::Status GetSequenceMapping(
EntryHandle<ct::SequenceMapping>* entry) const override {
return peer_->GetSequenceMapping(entry);
}
util::StatusOr<ct::ClusterNodeState> GetClusterNodeState() const override {
return peer_->GetClusterNodeState();
}
util::Status SetClusterNodeState(
const ct::ClusterNodeState& state) override {
return peer_->SetClusterNodeState(state);
}
void WatchServingSTH(const ConsistentStore::ServingSTHCallback& cb,
util::Task* task) override {
return peer_->WatchServingSTH(cb, task);
}
void WatchClusterNodeStates(
const ConsistentStore::ClusterNodeStateCallback& cb,
util::Task* task) override {
return peer_->WatchClusterNodeStates(cb, task);
}
void WatchClusterConfig(const ConsistentStore::ClusterConfigCallback& cb,
util::Task* task) override {
return peer_->WatchClusterConfig(cb, task);
}
private:
const MasterElection* const election_; // Not owned by us
const std::unique_ptr<ConsistentStore> peer_;
};
} // namespace
#endif // CERT_TRANS_LOG_STRICT_CONSISTENT_STORE_H_
|