start rewriting ASIO-related network service implementation

This commit is contained in:
Timur A. Fatkhullin
2024-09-16 23:28:18 +03:00
parent d33c101d70
commit 52de9a861b
3 changed files with 67 additions and 39 deletions

View File

@@ -5,6 +5,7 @@
#include <asio/basic_stream_socket.hpp>
#include <asio/bind_executor.hpp>
#include <asio/compose.hpp>
#include <asio/deferred.hpp>
#include <asio/ip/tcp.hpp>
#include <asio/ip/udp.hpp>
#include <asio/local/seq_packet_protocol.hpp>
@@ -13,6 +14,7 @@
#include <asio/steady_timer.hpp>
#include <asio/strand.hpp>
#include <asio/streambuf.hpp>
#include <asio/use_awaitable.hpp>
#include <asio/use_future.hpp>
#include <asio/write.hpp>
@@ -48,6 +50,26 @@ concept adc_asio_stream_transport_proto_c =
std::derived_from<T, asio::ip::tcp> || std::derived_from<T, asio::local::stream_protocol>;
template <typename T>
concept adc_asio_is_future = requires {
[]<typename AllocatorT>(std::type_identity<asio::use_future_t<AllocatorT>>) {
}(std::type_identity<std::remove_cvref_t<T>>());
};
template <typename T>
concept adc_asio_is_awaitable = requires {
[]<typename ExecutorT>(std::type_identity<asio::use_awaitable_t<ExecutorT>>) {
}(std::type_identity<std::remove_cvref_t<T>>());
};
struct adc_asio_async_call_ctx_t {
};
template <typename T>
concept adc_completion_token_c = traits::adc_is_callable<T> || std::same_as<T, adc_asio_async_call_ctx_t> ||
std::same_as<T, asio::deferred_t> || adc_asio_is_future<T> || adc_asio_is_awaitable<T>;
template <adc_asio_transport_proto_c TRANSPORT_PROTOT,
interfaces::adc_netsession_proto_c<std::string_view> SESSION_PROTOT,
traits::adc_output_char_range RMSGT = std::vector<char>>
@@ -67,6 +89,9 @@ public:
std::function<void(std::error_code, RMSGT)> receive_comp_token;
};
// to satisfy 'adc_netservice_c' concept
using async_call_ctx_t = adc_asio_async_call_ctx_t;
static constexpr std::chrono::duration DEFAULT_ACCEPT_TIMEOUT = std::chrono::years::max();
static constexpr std::chrono::duration DEFAULT_CONNECT_TIMEOUT = std::chrono::seconds(10);
static constexpr std::chrono::duration DEFAULT_SEND_TIMEOUT = std::chrono::seconds(5);
@@ -81,7 +106,10 @@ public:
virtual ~AdcNetServiceASIOBase() {}
netservice_ident_t ident() const { return _ident; }
netservice_ident_t ident() const
{
return _ident;
}
void clear()
@@ -92,39 +120,31 @@ public:
}
template <traits::adc_time_duration_c TimeoutT = decltype(DEFAULT_CONNECT_TIMEOUT)>
auto asyncConnect(const endpoint_t& endpoint,
asio_async_ctx_t& ctx,
const TimeoutT& timeout = DEFAULT_CONNECT_TIMEOUT)
template <adc_completion_token_c TokenT, traits::adc_time_duration_c TimeoutT = decltype(DEFAULT_CONNECT_TIMEOUT)>
auto asyncConnect(const endpoint_t& endpoint, TokenT&& token, const TimeoutT& timeout = DEFAULT_CONNECT_TIMEOUT)
{
static_assert(std::is_same_v<TokenT, async_call_ctx_t>, "'async_call_ctx_t'-TYPE MUST NOT BE USED!");
auto timer = getDeadlineTimer(timeout);
auto comp_token = [&ctx, timer = std::move(timer), this](std::error_code ec) {
auto comp_token = [wrapper = traits::adc_pf_wrapper(std::forward<TokenT>(token)),
timer = std::move(timer)](std::error_code ec) {
if (isTimeout(timer, ec)) {
ec = std::make_error_code(std::errc::timed_out);
} else {
timer->cancel();
}
if (!ctx.use_future) {
ctx.connect_comp_token(ec);
if constexpr (!adc_asio_is_future<TokenT>) {
std::get<0>(wrapper)(ec);
}
};
if (ctx.use_future) {
comp_token = asio::use_future(comp_token);
if constexpr (!adc_asio_is_future<TokenT>) {
return _socket.async_connect(endpoint, asio::use_future(std::move(comp_token)));
} else {
return _socket.async_connect(endpoint, std::move(comp_token));
}
return _socket.async_connect(endpoint, comp_token);
// if (ctx.use_future) {
// return _socket.async_connect(
// endpoint, asio::use_future([&ctx, timer = std::move(timer)](std::error_code) { timer->cancel(); }));
// } else {
// return _socket.async_connect(endpoint, [&ctx, timer = std::move(timer)](std::error_code ec) {
// timer->cancel();
// ctx.connect_comp_token(ec);
// });
// }
}
@@ -170,7 +190,7 @@ public:
auto timer = getDeadlineTimer(timeout);
auto comp_token = [&ctx, timer = std::move(timer)](std::error_code ec, size_t) {
auto comp_token = [&ctx, buff_seq, timer = std::move(timer)](std::error_code ec, size_t) {
timer->cancel();
if (!ctx.use_future) {
@@ -364,9 +384,15 @@ public:
return ftr.get();
}
void setShutdownType(asio::socket_base::shutdown_type shutdown_type) { _shutdownType = shutdown_type; }
void setShutdownType(asio::socket_base::shutdown_type shutdown_type)
{
_shutdownType = shutdown_type;
}
asio::socket_base::shutdown_type getShutdownType() const { return _shutdownType; }
asio::socket_base::shutdown_type getShutdownType() const
{
return _shutdownType;
}
std::error_code close()
{
@@ -415,7 +441,7 @@ protected:
}
template <typename TimerT>
bool isTimeout(const std::unique_ptr<TimerT>& timer, const std::error_code& ec)
static bool isTimeout(const std::unique_ptr<TimerT>& timer, const std::error_code& ec)
{
auto exp_time = timer->expiry();
return (exp_time < std::chrono::steady_clock::now()) && (ec == asio::error::operation_aborted);