Loading...
Searching...
No Matches
service_network.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#include <signal.h>
24
25#include <thread>
26
28#include "platform/proto/broadcast.pb.h"
29
30namespace resdb {
31
33 std::unique_ptr<ServiceInterface> service)
34 : service_(std::move(service)),
35 input_queue_("input"),
36 resp_queue_("resp"),
37 config_(config) {
38 struct sigaction sa;
39 sa.sa_handler = SIG_IGN;
40 sa.sa_flags = 0;
41 if (sigemptyset(&sa.sa_mask) == -1 || sigaction(SIGPIPE, &sa, 0) == -1) {
42 perror("failed to ignore SIGPIPE; sigaction");
43 exit(EXIT_FAILURE);
44 }
45
46 acceptor_ = std::make_unique<Acceptor>(config, &input_queue_);
47
48 async_acceptor_ = std::make_unique<AsyncAcceptor>(
49 config.GetSelfInfo().ip(), config_.GetSelfInfo().port() + 10000,
50 config.GetInputWorkerNum(),
51 std::bind(&ServiceNetwork::AcceptorHandler, this, std::placeholders::_1,
52 std::placeholders::_2));
53 async_acceptor_->StartAccept();
55}
56
58
59void ServiceNetwork::AcceptorHandler(const char* buffer, size_t data_len) {
60 BroadcastData data;
61 if (!data.ParseFromArray(buffer, data_len)) {
62 LOG(ERROR) << "parse broad cast fail:" << data_len;
63 return;
64 }
65
66 for (auto& sub_data : data.data()) {
67 std::unique_ptr<DataInfo> sub_request_info = std::make_unique<DataInfo>();
68 sub_request_info->data_len = sub_data.size();
69 sub_request_info->buff = new char[sub_request_info->data_len];
70 memcpy(sub_request_info->buff, sub_data.data(), sub_request_info->data_len);
71 std::unique_ptr<QueueItem> item = std::make_unique<QueueItem>();
72 item->socket = nullptr;
73 item->data = std::move(sub_request_info);
74 // LOG(ERROR) << "receve data from acceptor:" << data.is_resp()<<" data
75 // len:"<<item->data->data_len;
76 global_stats_->ServerCall();
77 input_queue_.Push(std::move(item));
78 }
79}
80
81void ServiceNetwork::InputProcess() {
82 std::vector<std::thread> threads;
83
84 int woker_num = config_.GetWorkerNum();
85 LOG(ERROR) << "server:" << config_.GetSelfInfo().id() << " start running";
86 for (int i = 0; i < woker_num; ++i) {
87 threads.push_back(std::thread([&]() {
88 while (IsRunning()) {
89 std::unique_ptr<QueueItem> item = input_queue_.Pop(1000);
90 if (item == nullptr) {
91 continue;
92 }
93 global_stats_->ServerProcess();
94 Process(std::move(item));
95 }
96 }));
97 }
98
99 for (auto& th : threads) {
100 if (th.joinable()) {
101 th.join();
102 }
103 }
104}
105
107 service_->Start();
108 auto input_th = std::thread(&ServiceNetwork::InputProcess, this);
109
110 acceptor_->Run();
111
112 input_th.join();
113}
114
115// Receive a message from network and pass it to service to process.
116void ServiceNetwork::Process(std::unique_ptr<QueueItem> item) {
117 auto client_socket =
118 item->socket == nullptr ? nullptr : std::move(item->socket);
119 auto request_info = std::move(item->data);
120 if (client_socket != nullptr) {
121 client_socket->SetSendTimeout(1000000);
122 }
123 std::unique_ptr<Context> context = std::make_unique<Context>();
124 context->client = std::make_unique<NetChannel>(std::move(client_socket),
125 /*connected=*/true);
126 if (request_info) {
127 service_->Process(std::move(context), std::move(request_info));
128 }
129 return;
130}
131
132bool ServiceNetwork::IsRunning() { return service_->IsRunning(); }
133
135 acceptor_->Stop();
136 service_->Stop();
137}
138
139bool ServiceNetwork::ServiceIsReady() const { return service_->IsReady(); }
140
141} // namespace resdb
std::string data
void Push(std::unique_ptr< T > data)
std::unique_ptr< T > Pop(int timeout_ms=100)
uint32_t GetInputWorkerNum() const
const ReplicaInfo & GetSelfInfo() const
ServiceNetwork(const ResDBConfig &config, std::unique_ptr< ServiceInterface > service)
static Stats * GetGlobalStats(int sleep_seconds=5)
Definition stats.cpp:29
Stats * global_stats_
std::unique_ptr< ResDBConfig > config_