22#include <glog/logging.h>
30 std::unique_ptr<TransactionManager> transaction_manager,
34 txn_db_(checkpoint_manager->GetTxnDB()),
39 [&](std::unique_ptr<Request> request,
40 std::unique_ptr<BatchUserResponse> resp_msg) {
41 if (request->is_recovery()) {
44 resp_msg->set_proxy_id(request->proxy_id());
45 resp_msg->set_seq(request->seq());
46 resp_msg->set_current_view(request->current_view());
48 if (transaction_executor_->NeedResponse() &&
49 resp_msg->proxy_id() != 0) {
50 queue_.
Push(std::move(resp_msg));
52 if (checkpoint_manager_) {
57 collector_pool_(std::make_unique<LockFreeCollectorPool>(
58 "txn",
config_.GetMaxProcessTxn(), transaction_executor_.get(),
59 config_.GetConfigData().enable_viewchange())) {
61 transaction_executor_->SetSeqUpdateNotifyFunc(
62 [&](uint64_t seq) { collector_pool_->Update(seq - 1); });
67 if (transaction_executor_) {
68 transaction_executor_->Stop();
80uint64_t MessageManager ::GetCurrentView()
const {
86 LOG(ERROR) <<
"set next seq:" << next_seq_;
92 std::unique_lock<std::mutex> lk(seq_mutex_);
93 uint32_t max_executed_seq = transaction_executor_->GetMaxPendingExecutedSeq();
94 global_stats_->
SeqGap(next_seq_ - max_executed_seq);
95 if (next_seq_ - max_executed_seq >
99 return absl::InvalidArgumentError(
"Seq has been used up.");
112bool MessageManager::IsValidMsg(
const Request& request) {
113 if (request.type() == Request::TYPE_RESPONSE) {
117 if (
static_cast<uint64_t
>(request.current_view()) !=
GetCurrentView()) {
118 LOG(ERROR) <<
"message view :[" << request.current_view()
123 if (
static_cast<uint64_t
>(request.seq()) <
124 transaction_executor_->GetMaxPendingExecutedSeq()) {
131bool MessageManager::MayConsensusChangeStatus(
132 int type,
int received_count, std::atomic<TransactionStatue>* status,
135 case Request::TYPE_PRE_PREPARE:
138 return status->compare_exchange_strong(
140 std::memory_order_acq_rel, std::memory_order_acq_rel);
143 case Request::TYPE_PREPARE:
147 return status->compare_exchange_strong(
149 std::memory_order_acq_rel, std::memory_order_acq_rel);
152 case Request::TYPE_COMMIT:
156 return status->compare_exchange_strong(
158 std::memory_order_acq_rel, std::memory_order_acq_rel);
173 const SignatureInfo& signature, std::unique_ptr<Request> request) {
174 if (request ==
nullptr || !IsValidMsg(*request)) {
177 int type = request->type();
178 uint64_t seq = request->seq();
179 int resp_received_count = 0;
180 int proxy_id = request->proxy_id();
182 int ret = collector_pool_->GetCollector(seq)->AddRequest(
183 std::move(request), signature, type == Request::TYPE_PRE_PREPARE,
184 [&](
const Request& request,
int received_count,
186 std::atomic<TransactionStatue>* status,
bool force) {
187 if (MayConsensusChangeStatus(type, received_count, status, force)) {
188 resp_received_count = 1;
193 }
else if (ret != 0) {
196 if (resp_received_count > 0) {
204 std::unique_lock<std::mutex> lk(data_mutex_);
205 for (uint64_t i = min_seq; i <= max_seq; ++i) {
206 if (committed_data_.find(i) == committed_data_.end()) {
207 LOG(ERROR) <<
"seq :" << i <<
" doesn't exist";
210 RequestWithProof* request = ret.add_requests();
211 *request->mutable_request() = committed_data_[i];
213 for (
const auto& request_info : committed_proof_[i]) {
214 RequestWithProof::RequestData*
data = request->add_proofs();
215 *
data->mutable_request() = *request_info->request;
216 *
data->mutable_signature() = request_info->signature;
226 return collector_pool_->GetCollector(seq)->GetPreparedProof();
230 return collector_pool_->GetCollector(seq)->GetStatus();
235 *state->mutable_replica_info() = config_.
GetSelfInfo();
241 return transaction_executor_->GetStorage();
252 auto value = last_committed_time_[proxy_id];
258 return collector_pool_->GetCollector(seq)->IsPrepared();
270 transaction_executor_->SetDuplicateManager(manager);
274 std::unique_ptr<BatchUserResponse> response =
275 std::make_unique<BatchUserResponse>();
278 response->set_hash(request->hash());
279 response->set_proxy_id(request->proxy_id());
280 response->set_seq(request->seq());
283 if (transaction_executor_->NeedResponse() && response->proxy_id() != 0) {
284 queue_.
Push(std::move(response));
289 return collector_pool_.get();
Request * Get(uint64_t seq)
uint64_t GetHighestPreparedSeq()
void SetExecutor(TransactionExecutor *executor)
void AddCommitData(std::unique_ptr< Request > request)
void SetHighestPreparedSeq(uint64_t seq)
void Push(std::unique_ptr< T > data)
std::unique_ptr< T > Pop(int timeout_ms=100)
void SetLastCommittedTime(uint64_t proxy_id)
void SetDuplicateManager(DuplicateManager *manager)
Request * GetRequest(uint64_t seq)
absl::StatusOr< uint64_t > AssignNextSeq()
TransactionStatue GetTransactionState(uint64_t seq)
std::vector< ReplicaInfo > GetReplicas()
uint64_t GetHighestPreparedSeq()
void SendResponse(std::unique_ptr< Request > request)
uint64_t GetCurrentView() const
uint64_t GetLastCommittedTime(uint64_t proxy_id)
void SetHighestPreparedSeq(uint64_t seq)
MessageManager(const ResDBConfig &config, std::unique_ptr< TransactionManager > transaction_manager, CheckPointManager *checkpoint_manager, SystemInfo *system_info)
int GetReplicaState(ReplicaState *state)
CollectorResultCode AddConsensusMsg(const SignatureInfo &signature, std::unique_ptr< Request > request)
std::vector< RequestInfo > GetPreparedProof(uint64_t seq)
bool IsPreapared(uint64_t seq)
int64_t GetCurrentPrimary() const
std::unique_ptr< BatchUserResponse > GetResponseMsg()
void SetNextSeq(uint64_t seq)
RequestSet GetRequestSet(uint64_t min_seq, uint64_t max_seq)
LockFreeCollectorPool * GetCollectorPool()
int GetMinDataReceiveNum() const
ResConfigData GetConfigData() const
uint32_t GetMaxProcessTxn() const
const ReplicaInfo & GetSelfInfo() const
static Stats * GetGlobalStats(int sleep_seconds=5)
void SeqGap(uint64_t seq_gap)
uint32_t GetPrimaryId() const
std::vector< ReplicaInfo > GetReplicas() const
uint64_t GetCurrentView() const
std::list< std::unique_ptr< RequestInfo > > CollectorDataType
CheckPointManager checkpoint_manager_
uint64_t GetCurrentTime()
std::unique_ptr< ResDBConfig > config_