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/uds_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 : : // UdsClientBuilder implementation
29 : :
30 : 11 : UdsClientBuilder::UdsClientBuilder(const std::string& socket_path)
31 : 11 : : socket_path_(socket_path),
32 : 11 : auto_start_(false),
33 : 11 : independent_context_(false),
34 : 11 : retry_interval_(base::constants::DEFAULT_RETRY_INTERVAL_MS),
35 : 11 : max_retries_(base::constants::DEFAULT_MAX_RETRIES),
36 : 11 : connection_timeout_(base::constants::DEFAULT_CONNECTION_TIMEOUT_MS),
37 : 22 : read_buffer_size_(base::constants::DEFAULT_READ_BUFFER_SIZE) {
38 [ + + + - : 17 : if (socket_path.empty()) throw diagnostics::BuilderException("Socket path cannot be empty");
+ - + - +
- ]
39 : :
40 : : // Ensure background IO service is running
41 : 10 : AutoInitializer::ensure_io_context_running();
42 : 12 : }
43 : :
44 : 10 : std::unique_ptr<wrapper::UdsClient> UdsClientBuilder::build() {
45 : 10 : std::unique_ptr<wrapper::UdsClient> client;
46 [ + + ]: 10 : if (independent_context_) {
47 : 6 : client = std::make_unique<wrapper::UdsClient>(socket_path_, std::make_shared<boost::asio::io_context>());
48 : 6 : client->manage_external_context(true);
49 : : } else {
50 : 4 : client = std::make_unique<wrapper::UdsClient>(socket_path_);
51 : : }
52 : :
53 [ + + + - : 10 : if (this->on_data_) client->on_data(this->on_data_);
+ - ]
54 [ + + + - : 10 : if (this->on_data_batch_) client->on_data_batch(this->on_data_batch_);
+ - ]
55 [ + + + - : 10 : if (this->on_connect_) client->on_connect(this->on_connect_);
+ - ]
56 [ + + + - : 10 : if (this->on_disconnect_) client->on_disconnect(this->on_disconnect_);
+ - ]
57 [ + + + - : 10 : if (this->on_error_) client->on_error(this->on_error_);
+ - ]
58 [ + + + - : 10 : if (this->on_backpressure_) client->on_backpressure(this->on_backpressure_);
+ - ]
59 : :
60 [ + + + - ]: 10 : if (retry_interval_set_) client->retry_interval(retry_interval_);
61 [ + + + - ]: 10 : if (max_retries_set_) client->max_retries(max_retries_);
62 [ + + + - ]: 10 : if (connection_timeout_set_) client->connection_timeout(connection_timeout_);
63 [ - + - - ]: 10 : if (read_buffer_size_set_) client->read_buffer_size(read_buffer_size_);
64 : :
65 [ + + + - ]: 10 : if (this->bp_strategy_set_) client->backpressure_strategy(this->bp_strategy_);
66 : 10 : client->backpressure_threshold(this->get_effective_backpressure_threshold());
67 : :
68 [ + + ]: 10 : if (this->framer_factory_) {
69 : 3 : client->framer(this->framer_factory_());
70 : : }
71 [ + + ]: 10 : if (this->on_message_) {
72 : 2 : client->on_message(this->on_message_);
73 : : }
74 [ + + ]: 10 : if (this->on_message_batch_) {
75 : 1 : client->on_message_batch(this->on_message_batch_);
76 : : }
77 : :
78 [ - + ]: 10 : if (auto_start_) {
79 : 0 : client->auto_start(true);
80 : : }
81 : :
82 : 10 : return client;
83 : 0 : }
84 : :
85 : 4 : UdsClientBuilder& UdsClientBuilder::auto_start(bool auto_start) {
86 : 4 : auto_start_ = auto_start;
87 : 4 : return *this;
88 : : }
89 : :
90 : 3 : UdsClientBuilder& UdsClientBuilder::retry_interval(std::chrono::milliseconds interval) {
91 : 3 : retry_interval_ = interval;
92 : 3 : retry_interval_set_ = true;
93 : 3 : return *this;
94 : : }
95 : :
96 : 3 : UdsClientBuilder& UdsClientBuilder::max_retries(int max_retries) {
97 : 3 : max_retries_ = max_retries;
98 : 3 : max_retries_set_ = true;
99 : 3 : return *this;
100 : : }
101 : :
102 : 3 : UdsClientBuilder& UdsClientBuilder::connection_timeout(std::chrono::milliseconds timeout) {
103 : 3 : connection_timeout_ = timeout;
104 : 3 : connection_timeout_set_ = true;
105 : 3 : return *this;
106 : : }
107 : :
108 : 0 : UdsClientBuilder& UdsClientBuilder::read_buffer_size(size_t bytes) {
109 : 0 : read_buffer_size_ = bytes;
110 : 0 : read_buffer_size_set_ = true;
111 : 0 : return *this;
112 : : }
113 : :
114 : 7 : UdsClientBuilder& UdsClientBuilder::independent_context(bool use_independent) {
115 : 7 : independent_context_ = use_independent;
116 : 7 : return *this;
117 : : }
118 : :
119 : : // UdsServerBuilder implementation
120 : :
121 : 12 : UdsServerBuilder::UdsServerBuilder(const std::string& socket_path)
122 : 12 : : socket_path_(socket_path),
123 : 12 : auto_start_(false),
124 : 12 : independent_context_(false),
125 : 12 : max_clients_(0),
126 : 12 : client_limit_enabled_(false),
127 : 12 : idle_timeout_(0),
128 : 12 : idle_timeout_set_(false),
129 : 12 : read_buffer_size_(base::constants::DEFAULT_READ_BUFFER_SIZE) {
130 [ + + + - : 18 : if (socket_path.empty()) throw diagnostics::BuilderException("Socket path cannot be empty");
+ - + - +
- ]
131 : :
132 : : // Ensure background IO service is running
133 : 11 : AutoInitializer::ensure_io_context_running();
134 : 13 : }
135 : :
136 : 10 : std::unique_ptr<wrapper::UdsServer> UdsServerBuilder::build() {
137 : 10 : std::unique_ptr<wrapper::UdsServer> server;
138 [ + + ]: 10 : if (independent_context_) {
139 : 5 : server = std::make_unique<wrapper::UdsServer>(socket_path_, std::make_shared<boost::asio::io_context>());
140 : 5 : server->manage_external_context(true);
141 : : } else {
142 : 5 : server = std::make_unique<wrapper::UdsServer>(socket_path_);
143 : : }
144 : :
145 [ + + + - : 10 : if (this->on_data_) server->on_data(this->on_data_);
+ - ]
146 [ + + + - : 10 : if (this->on_data_batch_) server->on_data_batch(this->on_data_batch_);
+ - ]
147 [ + + + - : 10 : if (this->on_connect_) server->on_connect(this->on_connect_);
+ - ]
148 [ + + + - : 10 : if (this->on_disconnect_) server->on_disconnect(this->on_disconnect_);
+ - ]
149 [ + + + - : 10 : if (this->on_error_) server->on_error(this->on_error_);
+ - ]
150 [ + + + - : 10 : if (this->on_backpressure_) server->on_backpressure(this->on_backpressure_);
+ - ]
151 : :
152 [ + + ]: 10 : if (client_limit_enabled_) {
153 : 5 : server->max_clients(max_clients_);
154 : : }
155 [ + + ]: 10 : if (idle_timeout_set_) {
156 : 3 : server->idle_timeout(idle_timeout_);
157 : : }
158 [ - + - - ]: 10 : if (read_buffer_size_set_) server->read_buffer_size(read_buffer_size_);
159 : :
160 [ + + + - ]: 10 : if (this->bp_strategy_set_) server->backpressure_strategy(this->bp_strategy_);
161 : 10 : server->backpressure_threshold(this->get_effective_backpressure_threshold());
162 : :
163 [ + + ]: 10 : if (this->framer_factory_) {
164 : : // Corrected: ServerInterface::framer expects FramerFactory std::function
165 : 4 : server->framer(this->framer_factory_);
166 : : }
167 [ + + ]: 10 : if (this->on_message_) {
168 : 3 : server->on_message(this->on_message_);
169 : : }
170 [ + + ]: 10 : if (this->on_message_batch_) {
171 : 1 : server->on_message_batch(this->on_message_batch_);
172 : : }
173 : :
174 [ - + ]: 10 : if (auto_start_) {
175 : 0 : server->auto_start(true);
176 : : }
177 : :
178 : 10 : return server;
179 : 0 : }
180 : :
181 : 4 : UdsServerBuilder& UdsServerBuilder::auto_start(bool auto_start) {
182 : 4 : auto_start_ = auto_start;
183 : 4 : return *this;
184 : : }
185 : :
186 : 6 : UdsServerBuilder& UdsServerBuilder::independent_context(bool use_independent) {
187 : 6 : independent_context_ = use_independent;
188 : 6 : return *this;
189 : : }
190 : :
191 : 3 : UdsServerBuilder& UdsServerBuilder::idle_timeout(std::chrono::milliseconds timeout) {
192 : 3 : idle_timeout_ = timeout;
193 : 3 : idle_timeout_set_ = true;
194 : 3 : return *this;
195 : : }
196 : :
197 : 0 : UdsServerBuilder& UdsServerBuilder::read_buffer_size(size_t bytes) {
198 : 0 : read_buffer_size_ = bytes;
199 : 0 : read_buffer_size_set_ = true;
200 : 0 : return *this;
201 : : }
202 : :
203 : 3 : UdsServerBuilder& UdsServerBuilder::max_clients(uint32_t max_clients) {
204 : 3 : max_clients_ = max_clients;
205 : 3 : client_limit_enabled_ = true;
206 : 3 : return *this;
207 : : }
208 : :
209 : 1 : UdsServerBuilder& UdsServerBuilder::single_client() {
210 : 1 : max_clients_ = 1;
211 : 1 : client_limit_enabled_ = true;
212 : 1 : return *this;
213 : : }
214 : :
215 : 2 : UdsServerBuilder& UdsServerBuilder::multi_client(size_t max) {
216 [ + + ]: 2 : if (max == 0) {
217 : 7 : throw diagnostics::BuilderException("multi_client max must be greater than 0");
218 : : }
219 : 1 : max_clients_ = static_cast<uint32_t>(max);
220 : 1 : client_limit_enabled_ = true;
221 : 1 : return *this;
222 : : }
223 : :
224 : : // Explicit template instantiations
225 : :
226 : : } // namespace builder
227 : : } // namespace wirestead
|