Loading...
Searching...
No Matches
message_manager.cpp
Go to the documentation of this file.
1/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19
21
22#include <glog/logging.h>
23
24#include "common/utils/utils.h"
25
26namespace resdb {
27
29 const ResDBConfig& config,
30 std::unique_ptr<TransactionManager> transaction_manager,
31 CheckPointManager* checkpoint_manager, SystemInfo* system_info)
32 : config_(config),
33 queue_("executed"),
34 txn_db_(checkpoint_manager->GetTxnDB()),
35 system_info_(system_info),
36 checkpoint_manager_(checkpoint_manager),
37 transaction_executor_(std::make_unique<TransactionExecutor>(
38 config,
39 [&](std::unique_ptr<Request> request,
40 std::unique_ptr<BatchUserResponse> resp_msg) {
41 if (request->is_recovery()) {
42 return;
43 }
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());
47 resp_msg->set_primary_id(GetCurrentPrimary());
48 if (transaction_executor_->NeedResponse() &&
49 resp_msg->proxy_id() != 0) {
50 queue_.Push(std::move(resp_msg));
51 }
52 if (checkpoint_manager_) {
53 checkpoint_manager_->AddCommitData(std::move(request));
54 }
55 },
56 system_info_, std::move(transaction_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); });
63 checkpoint_manager_->SetExecutor(transaction_executor_.get());
64}
65
67 if (transaction_executor_) {
68 transaction_executor_->Stop();
69 }
70}
71
72std::unique_ptr<BatchUserResponse> MessageManager::GetResponseMsg() {
73 return queue_.Pop();
74}
75
77 return system_info_->GetPrimaryId();
78}
79
80uint64_t MessageManager ::GetCurrentView() const {
82}
83
84void MessageManager::SetNextSeq(uint64_t seq) {
85 next_seq_ = seq;
86 LOG(ERROR) << "set next seq:" << next_seq_;
87}
88
89int64_t MessageManager::GetNextSeq() { return next_seq_; }
90
91absl::StatusOr<uint64_t> MessageManager::AssignNextSeq() {
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 >
96 static_cast<uint64_t>(config_.GetMaxProcessTxn())) {
97 // LOG(ERROR) << "next_seq_: " << next_seq_ << " max_executed_seq: " <<
98 // max_executed_seq;
99 return absl::InvalidArgumentError("Seq has been used up.");
100 }
101 return next_seq_++;
102}
103
104std::vector<ReplicaInfo> MessageManager::GetReplicas() {
105 return system_info_->GetReplicas();
106}
107
108// Check if the request is valid.
109// 1. view is the same as the current view
110// 2. seq is larger or equal than the next execute seq.
111// 3. inside the water mark.
112bool MessageManager::IsValidMsg(const Request& request) {
113 if (request.type() == Request::TYPE_RESPONSE) {
114 return true;
115 }
116 // view should be the same as the current one.
117 if (static_cast<uint64_t>(request.current_view()) != GetCurrentView()) {
118 LOG(ERROR) << "message view :[" << request.current_view()
119 << "] is older than the cur view :[" << GetCurrentView() << "]";
120 return false;
121 }
122
123 if (static_cast<uint64_t>(request.seq()) <
124 transaction_executor_->GetMaxPendingExecutedSeq()) {
125 return false;
126 }
127
128 return true;
129}
130
131bool MessageManager::MayConsensusChangeStatus(
132 int type, int received_count, std::atomic<TransactionStatue>* status,
133 bool ret) {
134 switch (type) {
135 case Request::TYPE_PRE_PREPARE:
136 if (*status == TransactionStatue::None) {
138 return status->compare_exchange_strong(
140 std::memory_order_acq_rel, std::memory_order_acq_rel);
141 }
142 break;
143 case Request::TYPE_PREPARE:
144 if (*status == TransactionStatue::READY_PREPARE &&
145 config_.GetMinDataReceiveNum() <= received_count) {
147 return status->compare_exchange_strong(
149 std::memory_order_acq_rel, std::memory_order_acq_rel);
150 }
151 break;
152 case Request::TYPE_COMMIT:
153 if (*status == TransactionStatue::READY_COMMIT &&
154 config_.GetMinDataReceiveNum() <= received_count) {
156 return status->compare_exchange_strong(
158 std::memory_order_acq_rel, std::memory_order_acq_rel);
159 return true;
160 }
161 break;
162 }
163 return ret;
164}
165
166// Add commit messages and return the number of messages have been received.
167// The commit messages only include post(pre-prepare), prepare and commit
168// messages. Messages are handled by state (PREPARE,COMMIT,READY_EXECUTE).
169
170// If there are enough messages and the state is changed after adding the
171// message, return 1, otherwise return 0. Return -2 if the request is not valid.
173 const SignatureInfo& signature, std::unique_ptr<Request> request) {
174 if (request == nullptr || !IsValidMsg(*request)) {
176 }
177 int type = request->type();
178 uint64_t seq = request->seq();
179 int resp_received_count = 0;
180 int proxy_id = request->proxy_id();
181
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;
189 }
190 });
191 if (ret == 1) {
192 SetLastCommittedTime(proxy_id);
193 } else if (ret != 0) {
195 }
196 if (resp_received_count > 0) {
198 }
200}
201
202RequestSet MessageManager::GetRequestSet(uint64_t min_seq, uint64_t max_seq) {
203 RequestSet ret;
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";
208 continue;
209 }
210 RequestWithProof* request = ret.add_requests();
211 *request->mutable_request() = committed_data_[i];
212 request->set_seq(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;
217 }
218 }
219 return ret;
220}
221
222// Get the transactions that have been execuited.
223Request* MessageManager::GetRequest(uint64_t seq) { return txn_db_->Get(seq); }
224
225std::vector<RequestInfo> MessageManager::GetPreparedProof(uint64_t seq) {
226 return collector_pool_->GetCollector(seq)->GetPreparedProof();
227}
228
230 return collector_pool_->GetCollector(seq)->GetStatus();
231}
232
233int MessageManager::GetReplicaState(ReplicaState* state) {
234 state->set_view(GetCurrentView());
235 *state->mutable_replica_info() = config_.GetSelfInfo();
236 *state->mutable_replica_config() = config_.GetConfigData();
237 return 0;
238}
239
241 return transaction_executor_->GetStorage();
242}
243
245 lct_lock_.lock();
246 last_committed_time_[proxy_id] = GetCurrentTime();
247 lct_lock_.unlock();
248}
249
250uint64_t MessageManager::GetLastCommittedTime(uint64_t proxy_id) {
251 lct_lock_.lock();
252 auto value = last_committed_time_[proxy_id];
253 lct_lock_.unlock();
254 return value;
255}
256
257bool MessageManager::IsPreapared(uint64_t seq) {
258 return collector_pool_->GetCollector(seq)->IsPrepared();
259}
260
262 return checkpoint_manager_->GetHighestPreparedSeq();
263}
264
266 return checkpoint_manager_->SetHighestPreparedSeq(seq);
267}
268
270 transaction_executor_->SetDuplicateManager(manager);
271}
272
273void MessageManager::SendResponse(std::unique_ptr<Request> request) {
274 std::unique_ptr<BatchUserResponse> response =
275 std::make_unique<BatchUserResponse>();
276 response->set_createtime(GetCurrentTime());
277 // response->set_local_id(batch_request.local_id());
278 response->set_hash(request->hash());
279 response->set_proxy_id(request->proxy_id());
280 response->set_seq(request->seq());
281 response->set_current_view(GetCurrentView());
282 response->set_primary_id(GetCurrentPrimary());
283 if (transaction_executor_->NeedResponse() && response->proxy_id() != 0) {
284 queue_.Push(std::move(response));
285 }
286}
287
289 return collector_pool_.get();
290}
291
292} // namespace resdb
std::string data
Request * Get(uint64_t seq)
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()
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)
Definition stats.cpp:29
void SeqGap(uint64_t seq_gap)
Definition stats.cpp:299
uint32_t GetPrimaryId() const
std::vector< ReplicaInfo > GetReplicas() const
uint64_t GetCurrentView() const
std::list< std::unique_ptr< RequestInfo > > CollectorDataType
CheckPointManager checkpoint_manager_
Stats * global_stats_
SystemInfo system_info_
uint64_t GetCurrentTime()
Definition utils.cpp:36
std::unique_ptr< ResDBConfig > config_