22#include <glog/logging.h>
34 "response",
config_.GetMaxProcessTxn(), nullptr)),
36 "context",
config_.GetMaxProcessTxn(), nullptr)),
37 batch_queue_(
"user request"),
46 .type() == CertificateKeyInfo::CLIENT ||
48 user_req_thread_ = std::thread(&ResponseManager::BatchProposeMsg,
this);
56 if (user_req_thread_.joinable()) {
57 user_req_thread_.join();
62int ResponseManager::GetPrimary() {
return system_info_->
GetPrimaryId(); }
65 std::vector<std::unique_ptr<Context>> context_list, uint64_t
id) {
66 return context_pool_->GetCollector(
id)->SetContextList(
67 id, std::move(context_list));
72 auto context = context_pool_->GetCollector(
id)->FetchContextList(
id);
73 context_pool_->Update(
id);
78 std::unique_ptr<Request> user_request) {
79 if (!user_request->need_response()) {
80 context->client =
nullptr;
83 std::unique_ptr<QueueItem> queue_item = std::make_unique<QueueItem>();
84 queue_item->context = std::move(context);
85 queue_item->user_request = std::move(user_request);
87 batch_queue_.
Push(std::move(queue_item));
95 std::unique_ptr<Request> request) {
96 std::unique_ptr<Request> response;
100 if (request->ret() == -2) {
101 LOG(ERROR) <<
"get response fail:" << request->ret();
106 AddResponseMsg(context->signature, std::move(request),
107 [&](
const Request& request,
109 response = std::make_unique<Request>(request);
114 BatchUserResponse batch_response;
115 if (batch_response.ParseFromString(response->data())) {
116 SendResponseToClient(batch_response);
118 LOG(ERROR) <<
"parse response fail:";
124bool ResponseManager::MayConsensusChangeStatus(
125 int type,
int received_count, std::atomic<TransactionStatue>* status) {
127 case Request::TYPE_RESPONSE:
132 return status->compare_exchange_strong(
134 std::memory_order_acq_rel);
142 const SignatureInfo& signature, std::unique_ptr<Request> request,
143 std::function<
void(
const Request&,
145 response_call_back) {
146 if (request ==
nullptr) {
150 int type = request->type();
151 uint64_t seq = request->seq();
152 int resp_received_count = 0;
153 int ret = collector_pool_->GetCollector(seq)->AddRequest(
154 std::move(request), signature,
false,
155 [&](
const Request& request,
int received_count,
157 std::atomic<TransactionStatue>* status,
bool force) {
158 if (MayConsensusChangeStatus(type, received_count, status)) {
159 resp_received_count = 1;
160 response_call_back(request,
data);
166 if (resp_received_count > 0) {
167 collector_pool_->Update(seq);
173void ResponseManager::SendResponseToClient(
174 const BatchUserResponse& batch_response) {
175 uint64_t create_time = batch_response.createtime();
176 uint64_t local_id = batch_response.local_id();
177 if (create_time > 0) {
181 LOG(ERROR) <<
"seq:" << local_id <<
" no resp";
189 std::vector<std::unique_ptr<Context>> context_list =
191 if (context_list.empty()) {
192 LOG(ERROR) <<
"context list is empty. local id:"
193 << batch_response.local_id();
197 for (
size_t i = 0; i < context_list.size(); ++i) {
198 auto& context = context_list[i];
199 if (context->client ==
nullptr) {
200 LOG(ERROR) <<
" no channel:";
203 int ret = context->client->SendRawMessageData(batch_response.response(i));
205 LOG(ERROR) <<
"send resp fail ret:" << ret;
211int ResponseManager::BatchProposeMsg() {
214 std::vector<std::unique_ptr<QueueItem>> batch_req;
217 LOG(ERROR) <<
"send num too high, wait:" << send_num_;
222 std::unique_ptr<QueueItem> item =
224 if (item !=
nullptr) {
225 batch_req.push_back(std::move(item));
231 if (batch_req.empty()) {
234 int ret = DoBatch(batch_req);
238 response.set_result(Response::ERROR);
239 for (
size_t i = 0; i < batch_req.size(); ++i) {
240 if (batch_req[i]->context && batch_req[i]->context->client) {
241 int ret = batch_req[i]->context->client->SendRawMessage(response);
243 LOG(ERROR) <<
"send resp" << response.DebugString()
244 <<
" fail ret:" << ret;
253int ResponseManager::DoBatch(
254 const std::vector<std::unique_ptr<QueueItem>>& batch_req) {
257 if (new_request ==
nullptr) {
260 std::vector<std::unique_ptr<Context>> context_list;
262 BatchUserRequest batch_request;
263 for (
size_t i = 0; i < batch_req.size(); ++i) {
264 BatchUserRequest::UserRequest* req = batch_request.add_user_requests();
265 *req->mutable_request() = *batch_req[i]->user_request.get();
266 *req->mutable_signature() = batch_req[i]->context->signature;
268 context_list.push_back(std::move(batch_req[i]->context));
272 LOG(ERROR) <<
"add context list:" << new_request->seq()
273 <<
" list size:" << context_list.size();
274 batch_request.set_local_id(local_id_);
277 LOG(ERROR) <<
"add context list fail:";
283 batch_request.SerializeToString(&
data);
286 if (!signature_or.ok()) {
287 LOG(ERROR) <<
"Sign message fail";
290 *new_request->mutable_data_signature() = *signature_or;
293 batch_request.SerializeToString(new_request->mutable_data());
295 new_request->set_proxy_id(config_.
GetSelfInfo().id());
296 replica_communicator_->
SendMessage(*new_request, GetPrimary());
298 LOG(INFO) <<
"send msg to primary:" << GetPrimary()
299 <<
" batch size:" << batch_req.size();
MockReplicaCommunicator replica_communicator_
void Push(std::unique_ptr< T > data)
std::unique_ptr< T > Pop(int timeout_ms=100)
virtual int SendMessage(const google::protobuf::Message &message)
int GetMinClientReceiveNum() const
uint32_t GetMaxProcessTxn() const
uint32_t ClientBatchNum() const
CertificateInfo GetPublicKeyCertificateInfo() const
const ReplicaInfo & GetSelfInfo() const
uint32_t ClientBatchWaitTimeMS() const
bool IsPerformanceRunning()
std::vector< std::unique_ptr< Context > > FetchContextList(uint64_t id)
ResponseManager(const ResDBConfig &config, ReplicaCommunicator *replica_communicator, SystemInfo *system_info, SignatureVerifier *verifier)
int ProcessResponseMsg(std::unique_ptr< Context > context, std::unique_ptr< Request > request)
int AddContextList(std::vector< std::unique_ptr< Context > > context, uint64_t id)
int NewUserRequest(std::unique_ptr< Context > context, std::unique_ptr< Request > user_request)
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
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_