22#include <glog/logging.h>
26#include "platform/proto/broadcast.pb.h"
32 bool is_use_long_conn,
int epoll_num,
int tcp_batch)
36 batch_queue_(
"bc_batch", tcp_batch),
37 is_use_long_conn_(is_use_long_conn) {
39 if (is_use_long_conn_) {
40 worker_ = std::make_unique<boost::asio::io_service::work>(io_service_);
41 for (
int i = 0; i < epoll_num; ++i) {
42 worker_threads_.push_back(std::thread([&]() { io_service_.run(); }));
61 if (broadcast_thread_.joinable()) {
62 broadcast_thread_.join();
64 if (is_use_long_conn_) {
65 for (
auto& cli : client_pools_) {
71 for (
auto& worker_th : worker_threads_) {
72 if (worker_th.joinable()) {
80 for (
auto& replica : replicas_) {
81 if (replica_info.ip() == replica.ip() &&
82 replica_info.port() == replica.port()) {
92 const std::vector<ReplicaInfo>& replicas) {
102 for (
const auto& replica : replicas_) {
103 NetChannel client(replica.ip(), replica.port());
113 broadcast_thread_ = std::thread([&]() {
115 std::vector<std::unique_ptr<QueueItem>> batch_req =
116 batch_queue_.
Pop(10000);
117 if (batch_req.empty()) {
120 BroadcastData broadcast_data;
121 for (
auto& queue_item : batch_req) {
122 broadcast_data.add_data()->swap(queue_item->data);
128 LOG(ERROR) <<
"broadcast request fail:";
136 if (is_use_long_conn_) {
137 auto item = std::make_unique<QueueItem>();
139 batch_queue_.
Push(std::move(item));
142 LOG(ERROR) <<
"send internal";
148 const ReplicaInfo& replica_info) {
149 if (is_use_long_conn_) {
151 BroadcastData broadcast_data;
152 broadcast_data.add_data()->swap(
data);
160 const std::vector<std::unique_ptr<Request>>& messages,
161 const ReplicaInfo& replica_info) {
162 if (is_use_long_conn_) {
163 BroadcastData broadcast_data;
164 for (
const auto& message : messages) {
166 broadcast_data.add_data()->swap(
data);
171 for (
const auto& message : messages) {
179 const google::protobuf::Message& message,
180 const std::vector<ReplicaInfo>& replicas) {
183 message.SerializeToString(&
data);
185 std::lock_guard<std::mutex> lk(mutex_);
186 for (
const auto& replica : replicas) {
188 if (client ==
nullptr) {
191 if (client->SendMessage(
data) == 0) {
194 LOG(ERROR) <<
"send to:" << replica.ip() <<
" fail";
201 const google::protobuf::Message& message,
202 const std::vector<ReplicaInfo>& replicas) {
204 for (
const auto& replica : replicas) {
205 auto client =
GetClient(replica.ip(), replica.port());
206 if (client ==
nullptr) {
209 if (verifier_ !=
nullptr) {
210 client->SetSignatureVerifier(verifier_);
212 if (client->SendRawMessage(message) == 0) {
220 const std::string& ip,
int port) {
221 if (client_pools_.find(std::make_pair(ip, port)) == client_pools_.end()) {
222 auto client = std::make_unique<AsyncReplicaClient>(
223 &io_service_, ip, port + (is_use_long_conn_ ? 10000 : 0),
true);
224 client_pools_[std::make_pair(ip, port)] = std::move(client);
226 return client_pools_[std::make_pair(ip, port)].get();
230 const std::string& ip,
int port) {
231 return std::make_unique<NetChannel>(ip, port);
237 LOG(ERROR) <<
"broadcast request fail:";
243 ReplicaInfo target_replica;
244 for (
const auto& replica : replicas_) {
245 if (replica.id() == node_id) {
246 target_replica = replica;
250 if (target_replica.ip().empty()) {
252 if (replica.id() == node_id) {
253 target_replica = replica;
259 if (target_replica.ip().empty()) {
260 LOG(ERROR) <<
"no replica info";
266 LOG(ERROR) <<
"broadcast request fail:";
std::vector< T > Pop(int timeout_ms)
virtual int SendRawMessage(const google::protobuf::Message &message)
static std::string GetRawMessageString(const google::protobuf::Message &message, SignatureVerifier *verifier=nullptr)
ReplicaCommunicator(const std::vector< ReplicaInfo > &replicas, SignatureVerifier *verifier=nullptr, bool is_use_long_conn=false, int epoll_num=1, int tcp_batch=100)
virtual void BroadCast(const google::protobuf::Message &message)
int SendMessageFromPool(const google::protobuf::Message &message, const std::vector< ReplicaInfo > &replicas)
virtual ~ReplicaCommunicator()
int SendMessageInternal(const google::protobuf::Message &message, const std::vector< ReplicaInfo > &replicas)
virtual std::unique_ptr< NetChannel > GetClient(const std::string &ip, int port)
virtual int SendBatchMessage(const std::vector< std::unique_ptr< Request > > &messages, const ReplicaInfo &replica_info)
virtual int SendHeartBeat(const Request &hb_info)
std::vector< ReplicaInfo > GetClientReplicas()
bool IsInPool(const ReplicaInfo &replica_info)
virtual int SendMessage(const google::protobuf::Message &message)
virtual AsyncReplicaClient * GetClientFromPool(const std::string &ip, int port)
void UpdateClientReplicas(const std::vector< ReplicaInfo > &replicas)
void StartBroadcastInBackGround()
static Stats * GetGlobalStats(int sleep_seconds=5)
void SendBroadCastMsg(uint32_t num)
void SendBroadCastMsgPerRep()
MockSignatureVerifier verifier_
std::vector< ReplicaInfo > replicas_