Loading...
Searching...
No Matches
geo_transaction_executor.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
25
26namespace resdb {
27
29 const ResDBConfig& config, std::unique_ptr<SystemInfo> system_info,
30 std::unique_ptr<ReplicaCommunicator> replica_communicator,
31 std::unique_ptr<TransactionManager> local_transaction_manager)
32 : TransactionManager(false, false),
33 config_(config),
34 system_info_(std::move(system_info)),
35 replica_communicator_(std::move(replica_communicator)),
36 local_transaction_manager_(std::move(local_transaction_manager)),
37 is_stop_(false) {
38 geo_thread_ = std::thread(&GeoTransactionExecutor::SendGeoMessages, this);
39}
40
42 is_stop_ = true;
43 if (geo_thread_.joinable()) {
44 geo_thread_.join();
45 }
46}
47
49
50void GeoTransactionExecutor::SendGeoMessages() {
51 std::vector<std::unique_ptr<Request>> messages;
52 while (!IsStop()) {
53 auto message = queue_.Pop(100);
54 if (message != nullptr) {
55 messages.push_back(std::move(message));
56 while (!IsStop() && messages.size() < batch_size_) {
57 auto message = queue_.Pop(0);
58 if (message == nullptr) {
59 break;
60 }
61 messages.push_back(std::move(message));
62 if (messages.size() >= batch_size_) {
63 break;
64 }
65 }
66 }
67 if (messages.size() > 0) {
68 SendBatchGeoMessage(messages);
69 messages.clear();
70 }
71 }
72 return;
73}
74
75void GeoTransactionExecutor::SendBatchGeoMessage(
76 const std::vector<std::unique_ptr<Request>>& batch_geo_request) {
77 ResConfigData config_data = config_.GetConfigData();
78
79 int self_send = replica_communicator_->SendBatchMessage(
80 batch_geo_request, config_.GetSelfInfo());
81 if (self_send < 0) {
82 LOG(ERROR) << "send batch_geo_request to self FAIL!";
83 }
84 // Only for primary node: send out GEO_REQUEST to other regions.
85 if (config_.GetSelfInfo().id() == system_info_->GetPrimaryId()) {
86 for (const auto& region : config_data.region()) {
87 if (region.region_id() == config_data.self_region_id()) {
88 continue;
89 }
90 // maximum number of faulty replicas in this region
91 int max_faulty = (region.replica_info_size() - 1) / 3;
92 int num_request_sent = 0;
93 for (const auto& replica : region.replica_info()) {
94 // send to f + 1 replicas in the region
95 if (num_request_sent > max_faulty) {
96 break;
97 }
98 int ret =
99 replica_communicator_->SendBatchMessage(batch_geo_request, replica);
100 if (ret >= 0) {
101 num_request_sent++;
102 }
103 }
104 }
105 // LOG(ERROR) << "local executor send out geo message";
106 }
107}
108
109std::unique_ptr<BatchUserResponse> GeoTransactionExecutor::ExecuteBatch(
110 const BatchUserRequest& request) {
111 std::unique_ptr<Request> geo_request = resdb::NewRequest(
112 Request::TYPE_GEO_REQUEST, Request(), config_.GetSelfInfo().id(),
113 config_.GetConfigData().self_region_id());
114
115 geo_request->set_seq(request.seq());
116 geo_request->set_proxy_id(request.proxy_id());
117 geo_request->set_hash(SignatureVerifier::CalculateHash(
118 geo_request->data() + std::to_string(request.seq()) +
119 std::to_string(config_.GetConfigData().self_region_id())));
120
121 request.SerializeToString(geo_request->mutable_data());
122
123 queue_.Push(std::move(geo_request));
124 return nullptr;
125}
126
127} // namespace resdb
MockReplicaCommunicator replica_communicator_
virtual std::unique_ptr< BatchUserResponse > ExecuteBatch(const BatchUserRequest &request) override
GeoTransactionExecutor(const ResDBConfig &config, std::unique_ptr< SystemInfo > system_info, std::unique_ptr< ReplicaCommunicator > replica_communicator, std::unique_ptr< TransactionManager > local_transaction_manager)
std::unique_ptr< SystemInfo > system_info_
std::unique_ptr< ReplicaCommunicator > replica_communicator_
void Push(std::unique_ptr< T > data)
std::unique_ptr< T > Pop(int timeout_ms=100)
ResConfigData GetConfigData() const
const ReplicaInfo & GetSelfInfo() const
static std::string CalculateHash(const std::string &str)
SystemInfo system_info_
std::unique_ptr< Request > NewRequest(Request::Type type, const Request &request, int sender_id)
std::unique_ptr< ResDBConfig > config_