22#include <glog/logging.h>
51 "response",
config_.GetMaxProcessTxn(), nullptr)),
53 "context",
config_.GetMaxProcessTxn(), nullptr)),
54 batch_queue_(
"user request"),
58 eval_started_ =
false;
59 eval_ready_future_ = eval_ready_promise_.get_future();
63 .type() == CertificateKeyInfo::CLIENT) {
64 for (
int i = 0; i < 2; ++i) {
66 std::thread(&PerformanceManager::BatchProposeMsg,
this);
70 checking_timeout_thread_ =
71 std::thread(&PerformanceManager::MonitoringClientTimeOut,
this);
74 send_num_.push_back(0);
77 timeout_length_ = 10000000;
82 for (
int i = 0; i < 16; ++i) {
83 if (user_req_thread_[i].joinable()) {
84 user_req_thread_[i].join();
87 if (checking_timeout_thread_.joinable()) {
88 checking_timeout_thread_.join();
93int PerformanceManager::GetPrimary() {
return system_info_->
GetPrimaryId(); }
95std::unique_ptr<Request> PerformanceManager::GenerateUserRequest() {
96 std::unique_ptr<Request> request = std::make_unique<Request>();
97 request->set_data(data_func_());
102 data_func_ = std::move(func);
109 eval_started_ =
true;
110 for (
int i = 0; i < 60000000000; ++i) {
111 std::unique_ptr<QueueItem> queue_item = std::make_unique<QueueItem>();
112 queue_item->context =
nullptr;
113 queue_item->user_request = GenerateUserRequest();
114 batch_queue_.
Push(std::move(queue_item));
116 eval_ready_promise_.set_value(
true);
119 LOG(WARNING) <<
"start eval done";
127 std::unique_ptr<Request> request) {
128 std::unique_ptr<Request> response;
129 std::string hash = request->hash();
130 int32_t primary_id = request->primary_id();
131 uint64_t seq = request->seq();
135 if (request->ret() == -2) {
138 RemoveWaitingResponseRequest(hash);
142 AddResponseMsg(context->signature, std::move(request),
143 [&](
const Request& request,
145 response = std::make_unique<Request>(request);
150 BatchUserResponse batch_response;
151 if (batch_response.ParseFromString(response->data())) {
152 if (seq > highest_seq_) {
154 if (highest_seq_primary_id_ != primary_id) {
156 highest_seq_primary_id_ = primary_id;
159 SendResponseToClient(batch_response);
160 RemoveWaitingResponseRequest(hash);
162 LOG(ERROR) <<
"parse response fail:";
168bool PerformanceManager::MayConsensusChangeStatus(
169 int type,
int received_count, std::atomic<TransactionStatue>* status) {
171 case Request::TYPE_RESPONSE:
176 return status->compare_exchange_strong(
178 std::memory_order_acq_rel);
186 const SignatureInfo& signature, std::unique_ptr<Request> request,
187 std::function<
void(
const Request&,
189 response_call_back) {
190 if (request ==
nullptr) {
194 int type = request->type();
195 uint64_t seq = request->seq();
196 int resp_received_count = 0;
197 int ret = collector_pool_->GetCollector(seq)->AddRequest(
198 std::move(request), signature,
false,
199 [&](
const Request& request,
int received_count,
201 std::atomic<TransactionStatue>* status,
bool force) {
202 if (MayConsensusChangeStatus(type, received_count, status)) {
203 resp_received_count = 1;
204 response_call_back(request,
data);
210 if (resp_received_count > 0) {
211 collector_pool_->Update(seq);
217void PerformanceManager::SendResponseToClient(
218 const BatchUserResponse& batch_response) {
219 uint64_t create_time = batch_response.createtime();
220 uint64_t local_id = batch_response.local_id();
221 if (create_time > 0) {
225 LOG(ERROR) <<
"seq:" << local_id <<
" no resp";
229 if (send_num_[batch_response.primary_id()] > 0) {
230 send_num_[batch_response.primary_id()]--;
240int PerformanceManager::BatchProposeMsg() {
244 std::vector<std::unique_ptr<QueueItem>> batch_req;
245 eval_ready_future_.get();
253 std::unique_ptr<QueueItem> item =
255 if (item ==
nullptr) {
258 batch_req.push_back(std::move(item));
263 int ret = DoBatch(batch_req);
267 response.set_result(Response::ERROR);
268 for (
size_t i = 0; i < batch_req.size(); ++i) {
269 if (batch_req[i]->context && batch_req[i]->context->client) {
270 int ret = batch_req[i]->context->client->SendRawMessage(response);
272 LOG(ERROR) <<
"send resp" << response.DebugString()
273 <<
" fail ret:" << ret;
282int PerformanceManager::DoBatch(
283 const std::vector<std::unique_ptr<QueueItem>>& batch_req) {
286 if (new_request ==
nullptr) {
289 std::vector<std::unique_ptr<Context>> context_list;
291 BatchUserRequest batch_request;
292 for (
size_t i = 0; i < batch_req.size(); ++i) {
293 BatchUserRequest::UserRequest* req = batch_request.add_user_requests();
294 *req->mutable_request() = *batch_req[i]->user_request.get();
295 if (batch_req[i]->context) {
296 *req->mutable_signature() = batch_req[i]->context->signature;
302 batch_request.SerializeToString(new_request->mutable_data());
304 auto signature_or = verifier_->
SignMessage(new_request->data());
305 if (!signature_or.ok()) {
306 LOG(ERROR) <<
"Sign message fail";
309 *new_request->mutable_data_signature() = *signature_or;
313 new_request->set_proxy_id(config_.
GetSelfInfo().id());
315 replica_communicator_->
SendMessage(*new_request, GetPrimary());
317 send_num_[GetPrimary()]++;
318 if (total_num_++ == 1000000) {
320 LOG(WARNING) <<
"total num is done:" << total_num_;
322 if (total_num_ % 10000 == 0) {
323 LOG(WARNING) <<
"total num is :" << total_num_;
326 AddWaitingResponseRequest(std::move(new_request));
330void PerformanceManager::AddWaitingResponseRequest(
331 std::unique_ptr<Request> request) {
337 client_timeout_min_heap_.push(
338 PerformanceClientTimeout(request->hash(), time));
339 waiting_response_batches_.insert(
340 make_pair(request->hash(), std::move(request)));
342 sem_post(&request_sent_signal_);
345void PerformanceManager::RemoveWaitingResponseRequest(std::string hash) {
350 if (waiting_response_batches_.find(hash) != waiting_response_batches_.end()) {
351 waiting_response_batches_.erase(waiting_response_batches_.find(hash));
356bool PerformanceManager::CheckTimeOut(std::string hash) {
359 (waiting_response_batches_.find(hash) != waiting_response_batches_.end());
364std::unique_ptr<Request> PerformanceManager::GetTimeOutRequest(
367 auto value = std::move(waiting_response_batches_.find(hash)->second);
372void PerformanceManager::MonitoringClientTimeOut() {
374 sem_wait(&request_sent_signal_);
376 if (client_timeout_min_heap_.empty()) {
380 auto client_timeout = client_timeout_min_heap_.top();
381 client_timeout_min_heap_.pop();
388 if (CheckTimeOut(client_timeout.hash)) {
389 auto request = GetTimeOutRequest(client_timeout.hash);
391 LOG(ERROR) <<
"Client Request Timeout " << client_timeout.hash;
392 replica_communicator_->
BroadCast(*request);
MockReplicaCommunicator replica_communicator_
void Push(std::unique_ptr< T > data)
std::unique_ptr< T > Pop(int timeout_ms=100)
virtual void BroadCast(const google::protobuf::Message &message)
virtual int SendMessage(const google::protobuf::Message &message)
int GetMinClientReceiveNum() const
size_t GetReplicaNum() const
ResConfigData GetConfigData() const
uint32_t GetMaxProcessTxn() const
uint32_t ClientBatchNum() const
CertificateInfo GetPublicKeyCertificateInfo() const
const ReplicaInfo & GetSelfInfo() const
uint32_t ClientBatchWaitTimeMS() const
bool IsPerformanceRunning()
static std::string CalculateHash(const std::string &str)
virtual absl::StatusOr< SignatureInfo > SignMessage(const std::string &message)
static Stats * GetGlobalStats(int sleep_seconds=5)
void AddLatency(uint64_t run_time)
uint32_t GetPrimaryId() const
void SetPrimary(uint32_t id)
std::list< std::unique_ptr< RequestInfo > > CollectorDataType
MockSignatureVerifier verifier_
std::unique_ptr< Request > NewRequest(Request::Type type, const Request &request, int sender_id)
uint64_t GetCurrentTime()
std::unique_ptr< ResDBConfig > config_