Branch data Line data Source code
1 : : /*
2 : : * Copyright 2025 Jinwoo Sung
3 : : *
4 : : * Licensed under the Apache License, Version 2.0 (the "License");
5 : : * you may not use this file except in compliance with the License.
6 : : * You may obtain a copy of the License at
7 : : *
8 : : * http://www.apache.org/licenses/LICENSE-2.0
9 : : *
10 : : * Unless required by applicable law or agreed to in writing, software
11 : : * distributed under the License is distributed on an "AS IS" BASIS,
12 : : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 : : * See the License for the specific language governing permissions and
14 : : * limitations under the License.
15 : : */
16 : :
17 : : #include "wirestead/builder/tcp_client_builder.hpp"
18 : :
19 : : #include <boost/asio/io_context.hpp>
20 : :
21 : : #include "wirestead/base/constants.hpp"
22 : : #include "wirestead/builder/auto_initializer.hpp"
23 : : #include "wirestead/diagnostics/exceptions.hpp"
24 : :
25 : : namespace wirestead {
26 : : namespace builder {
27 : :
28 : 96 : TcpClientBuilder::TcpClientBuilder(const std::string& host, uint16_t port)
29 : 96 : : host_(host),
30 : 96 : port_(port),
31 : 96 : auto_start_(false),
32 : 96 : independent_context_(false),
33 : 96 : retry_interval_(base::constants::DEFAULT_RETRY_INTERVAL_MS),
34 : 96 : max_retries_(base::constants::DEFAULT_MAX_RETRIES),
35 : 96 : connection_timeout_(base::constants::DEFAULT_CONNECTION_TIMEOUT_MS),
36 : 192 : idle_timeout_(0),
37 : 96 : idle_timeout_action_(IdleTimeoutAction::Reconnect),
38 : 96 : tcp_no_delay_(true),
39 : 96 : keep_alive_(false),
40 : 96 : send_buffer_size_(0),
41 : 96 : receive_buffer_size_(0),
42 : 288 : read_buffer_size_(base::constants::DEFAULT_READ_BUFFER_SIZE) {
43 [ + + + - : 108 : if (port == 0) throw diagnostics::BuilderException("Invalid port number: 0");
+ - + - +
- ]
44 [ + + + - : 106 : if (host.empty()) throw diagnostics::BuilderException("Host cannot be empty");
+ - + - +
- ]
45 : :
46 : : // Ensure background IO service is running
47 : 92 : AutoInitializer::ensure_io_context_running();
48 : 104 : }
49 : :
50 : 92 : std::unique_ptr<wrapper::TcpClient> TcpClientBuilder::build() {
51 : 92 : std::unique_ptr<wrapper::TcpClient> client;
52 [ + + ]: 92 : if (independent_context_) {
53 : 3 : client = std::make_unique<wrapper::TcpClient>(host_, port_, std::make_shared<boost::asio::io_context>());
54 : 3 : client->manage_external_context(true);
55 : : } else {
56 : 89 : client = std::make_unique<wrapper::TcpClient>(host_, port_);
57 : : }
58 : :
59 [ + + + - : 92 : if (this->on_data_) client->on_data(this->on_data_);
+ - ]
60 [ + + + - : 92 : if (this->on_data_batch_) client->on_data_batch(this->on_data_batch_);
+ - ]
61 [ + + + - : 92 : if (this->on_connect_) client->on_connect(this->on_connect_);
+ - ]
62 [ + + + - : 92 : if (this->on_disconnect_) client->on_disconnect(this->on_disconnect_);
+ - ]
63 [ + + + - : 92 : if (this->on_error_) client->on_error(this->on_error_);
+ - ]
64 [ + + + - : 92 : if (this->on_backpressure_) client->on_backpressure(this->on_backpressure_);
+ - ]
65 : :
66 [ + + + - ]: 92 : if (retry_interval_set_) client->retry_interval(retry_interval_);
67 [ + + + - ]: 92 : if (max_retries_set_) client->max_retries(max_retries_);
68 [ - + - - ]: 92 : if (tls_enabled_) client->tls(tls_ca_file_);
69 [ + + + - ]: 92 : if (connection_timeout_set_) client->connection_timeout(connection_timeout_);
70 [ + + + - ]: 92 : if (idle_timeout_set_) client->idle_timeout(idle_timeout_);
71 [ + + + - ]: 92 : if (idle_timeout_action_set_) client->idle_timeout_action(idle_timeout_action_);
72 [ + + + - ]: 92 : if (tcp_no_delay_set_) client->tcp_no_delay(tcp_no_delay_);
73 [ + + + - ]: 92 : if (keep_alive_set_) client->keep_alive(keep_alive_);
74 [ + + + - ]: 92 : if (send_buffer_size_set_) client->send_buffer_size(send_buffer_size_);
75 [ + + + - ]: 92 : if (receive_buffer_size_set_) client->receive_buffer_size(receive_buffer_size_);
76 [ - + - - ]: 92 : if (read_buffer_size_set_) client->read_buffer_size(read_buffer_size_);
77 : :
78 [ + + + - ]: 92 : if (this->bp_strategy_set_) client->backpressure_strategy(this->bp_strategy_);
79 : 92 : client->backpressure_threshold(this->get_effective_backpressure_threshold());
80 : :
81 [ + + ]: 92 : if (this->framer_factory_) {
82 : 1 : client->framer(this->framer_factory_());
83 : : }
84 [ + + ]: 92 : if (this->on_message_) {
85 : 1 : client->on_message(this->on_message_);
86 : : }
87 [ + + ]: 92 : if (this->on_message_batch_) {
88 : 1 : client->on_message_batch(this->on_message_batch_);
89 : : }
90 : :
91 [ + + ]: 92 : if (auto_start_) {
92 : 8 : client->auto_start(true);
93 : : }
94 : :
95 : 92 : return client;
96 : 0 : }
97 : :
98 : 11 : TcpClientBuilder& TcpClientBuilder::auto_start(bool auto_start) {
99 : 11 : auto_start_ = auto_start;
100 : 11 : return *this;
101 : : }
102 : :
103 : 4 : TcpClientBuilder& TcpClientBuilder::retry_interval(std::chrono::milliseconds interval) {
104 : 4 : retry_interval_ = interval;
105 : 4 : retry_interval_set_ = true;
106 : 4 : return *this;
107 : : }
108 : :
109 : 9 : TcpClientBuilder& TcpClientBuilder::max_retries(int max_retries) {
110 : 9 : max_retries_ = max_retries;
111 : 9 : max_retries_set_ = true;
112 : 9 : return *this;
113 : : }
114 : :
115 : 0 : TcpClientBuilder& TcpClientBuilder::tls(const std::string& ca_file) {
116 : 0 : tls_enabled_ = true;
117 : 0 : tls_ca_file_ = ca_file;
118 : 0 : return *this;
119 : : }
120 : :
121 : 1 : TcpClientBuilder& TcpClientBuilder::connection_timeout(std::chrono::milliseconds timeout) {
122 : 1 : connection_timeout_ = timeout;
123 : 1 : connection_timeout_set_ = true;
124 : 1 : return *this;
125 : : }
126 : :
127 : 4 : TcpClientBuilder& TcpClientBuilder::idle_timeout(std::chrono::milliseconds timeout) {
128 : 4 : idle_timeout_ = timeout;
129 : 4 : idle_timeout_set_ = true;
130 : 4 : return *this;
131 : : }
132 : :
133 : 3 : TcpClientBuilder& TcpClientBuilder::idle_timeout_action(IdleTimeoutAction action) {
134 : 3 : idle_timeout_action_ = action;
135 : 3 : idle_timeout_action_set_ = true;
136 : 3 : return *this;
137 : : }
138 : :
139 : 3 : TcpClientBuilder& TcpClientBuilder::independent_context(bool use_independent) {
140 : 3 : independent_context_ = use_independent;
141 : 3 : return *this;
142 : : }
143 : :
144 : 1 : TcpClientBuilder& TcpClientBuilder::tcp_no_delay(bool enable) {
145 : 1 : tcp_no_delay_ = enable;
146 : 1 : tcp_no_delay_set_ = true;
147 : 1 : return *this;
148 : : }
149 : :
150 : 1 : TcpClientBuilder& TcpClientBuilder::keep_alive(bool enable) {
151 : 1 : keep_alive_ = enable;
152 : 1 : keep_alive_set_ = true;
153 : 1 : return *this;
154 : : }
155 : :
156 : 1 : TcpClientBuilder& TcpClientBuilder::send_buffer_size(size_t bytes) {
157 : 1 : send_buffer_size_ = bytes;
158 : 1 : send_buffer_size_set_ = true;
159 : 1 : return *this;
160 : : }
161 : :
162 : 1 : TcpClientBuilder& TcpClientBuilder::receive_buffer_size(size_t bytes) {
163 : 1 : receive_buffer_size_ = bytes;
164 : 1 : receive_buffer_size_set_ = true;
165 : 1 : return *this;
166 : : }
167 : :
168 : 0 : TcpClientBuilder& TcpClientBuilder::read_buffer_size(size_t bytes) {
169 : 0 : read_buffer_size_ = bytes;
170 : 0 : read_buffer_size_set_ = true;
171 : 0 : return *this;
172 : : }
173 : :
174 : : // Explicit template instantiations
175 : :
176 : : } // namespace builder
177 : : } // namespace wirestead
|