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 : : #pragma once
18 : :
19 : : #include <memory>
20 : : #include <optional>
21 : : #include <string>
22 : : #include <variant>
23 : : #include <vector>
24 : :
25 : : #include "wirestead/base/constants.hpp"
26 : : #include "wirestead/base/platform.hpp"
27 : : #include "wirestead/base/visibility.hpp"
28 : : #include "wirestead/config/tcp_client_config.hpp"
29 : : #include "wirestead/diagnostics/error_types.hpp"
30 : : #include "wirestead/interface/channel.hpp"
31 : : #include "wirestead/memory/memory_pool.hpp"
32 : : #include "wirestead/transport/base/reconnect_policy.hpp"
33 : :
34 : : // Forward declare boost components
35 : : namespace boost {
36 : : namespace asio {
37 : : class io_context;
38 : : }
39 : : } // namespace boost
40 : :
41 : : namespace wirestead {
42 : : namespace transport {
43 : :
44 : : using base::LinkState;
45 : : using config::TcpClientConfig;
46 : : using interface::Channel;
47 : :
48 : : // Use static create() helpers to construct safely
49 : : class WIRESTEAD_API TcpClient : public Channel, public std::enable_shared_from_this<TcpClient> {
50 : : public:
51 : : using BufferVariant =
52 : : std::variant<memory::PooledBuffer, std::vector<uint8_t>, std::shared_ptr<const std::vector<uint8_t>>>;
53 : :
54 : : static std::shared_ptr<TcpClient> create(const TcpClientConfig& cfg);
55 : : static std::shared_ptr<TcpClient> create(const TcpClientConfig& cfg, boost::asio::io_context& ioc);
56 : : ~TcpClient() override;
57 : :
58 : : // Move semantics
59 : : TcpClient(TcpClient&&) noexcept;
60 : : TcpClient& operator=(TcpClient&&) noexcept;
61 : :
62 : : // Disable copy (should be already disabled by unique_ptr, but being explicit)
63 : : TcpClient(const TcpClient&) = delete;
64 : : TcpClient& operator=(const TcpClient&) = delete;
65 : :
66 : : void start() override;
67 : : void stop() override;
68 : : bool is_connected() const override;
69 : : bool is_backpressure_active() const override;
70 : : wrapper::RuntimeStats stats() const override;
71 : : void reset_stats() override;
72 : : boost::asio::any_io_executor get_executor() override;
73 : :
74 : : bool async_write_copy(memory::ConstByteSpan data) override;
75 : : bool async_write_move(std::vector<uint8_t>&& data) override;
76 : : bool async_write_shared(std::shared_ptr<const std::vector<uint8_t>> data) override;
77 : : bool async_try_write_copy(memory::ConstByteSpan data) override;
78 : : bool async_try_write_move(std::vector<uint8_t>&& data) override;
79 : : bool async_try_write_shared(std::shared_ptr<const std::vector<uint8_t>> data) override;
80 : :
81 : : // Thread-safe: may be called at any time, including after start(). Each
82 : : // setter takes effect for subsequent operations (callback replacement is
83 : : // synchronized against concurrent reads on the io thread; see #436).
84 : : void on_bytes(OnBytes cb) override;
85 : : void on_state(OnState cb) override;
86 : : void on_backpressure(OnBackpressure cb) override;
87 : :
88 : : std::optional<diagnostics::ErrorInfo> last_error_info() const override;
89 : :
90 : : // Dynamic configuration methods. Thread-safe; take effect for the next
91 : : // reconnect/idle-timeout decision, not retroactively for one already in
92 : : // flight.
93 : : void set_backpressure_strategy(base::constants::BackpressureStrategy strategy);
94 : : void set_retry_interval(unsigned interval_ms);
95 : : void set_max_retries(int max_retries);
96 : : void set_connection_timeout(unsigned timeout_ms);
97 : : void set_idle_timeout(unsigned timeout_ms);
98 : : void set_idle_timeout_action(IdleTimeoutAction action);
99 : : void set_reconnect_policy(ReconnectPolicy policy);
100 : :
101 : : private:
102 : : explicit TcpClient(const TcpClientConfig& cfg);
103 : : explicit TcpClient(const TcpClientConfig& cfg, boost::asio::io_context& ioc);
104 : :
105 : : struct Impl;
106 : 7339 : const Impl* get_impl() const { return impl_.get(); }
107 : : Impl* get_impl() { return impl_.get(); }
108 : : std::unique_ptr<Impl> impl_;
109 : : };
110 : : } // namespace transport
111 : : } // namespace wirestead
|