This commit is contained in:
Timur A. Fatkhullin 2024-06-10 18:04:46 +03:00
parent 02811a92b5
commit 1f9615a6ba
3 changed files with 83 additions and 19 deletions

View File

@ -37,6 +37,10 @@ option(SPDLOG_LIBRARY "Use SPDLOG library for logging" ON)
if (SPDLOG_LIBRARY) if (SPDLOG_LIBRARY)
find_package(spdlog REQUIRED) find_package(spdlog REQUIRED)
set(ADC_COMMON_HEADERS ${ADC_COMMON_HEADERS}
common/adc_spdlog.h
)
set(ADC_NETWORK_HEADERS ${ADC_NETWORK_HEADERS} set(ADC_NETWORK_HEADERS ${ADC_NETWORK_HEADERS}
net/adc_netserver_spdlog.h net/adc_netserver_spdlog.h
) )

View File

@ -7,6 +7,8 @@ ABSTRACT DEVICE COMPONENTS LIBRARY
*/ */
#include <filesystem> #include <filesystem>
#include <set>
#include <unordered_map>
#if __has_include(<unistd.h>) // POSIX #if __has_include(<unistd.h>) // POSIX
#define FORK_EXISTS 1 #define FORK_EXISTS 1
#include <sys/stat.h> #include <sys/stat.h>
@ -103,6 +105,15 @@ concept adc_netserver_session_c = requires {
namespace traits namespace traits
{ {
template <typename T>
concept adc_generic_netserver_impl_c = requires(T t, const T t_const) {
typename T::server_ident_t;
{ t_const.serverIdent() } -> std::same_as<typename T::server_ident_t>;
{ t.start() } -> std::same_as<void>;
{ t.stop() } -> std::same_as<void>;
};
template <typename T> template <typename T>
concept adc_netserver_impl_c = requires(T t, const T t_const) { concept adc_netserver_impl_c = requires(T t, const T t_const) {
typename T::server_ident_t; typename T::server_ident_t;
@ -110,12 +121,54 @@ concept adc_netserver_impl_c = requires(T t, const T t_const) {
{ t_const.serverIdent() } -> std::same_as<typename T::server_ident_t>; { t_const.serverIdent() } -> std::same_as<typename T::server_ident_t>;
{ t.start() } -> std::same_as<void>; { t.start() } -> std::same_as<void>;
{ t.stop() } -> std::same_as<void>; { t.stop() } -> std::same_as<void>;
{ t.daemonize() } -> std::same_as<void>;
{ t.daemonizePrepare() } -> std::same_as<void>; { t.daemonizePrepare() } -> std::same_as<void>;
{ t.daemonizeFinalize() } -> std::same_as<void>; { t.daemonizeFinalize() } -> std::same_as<void>;
}; };
} // namespace traits } // namespace traits
/* VERY GENERIC NETWORK SERVER INTERFACE */
template <traits::adc_generic_netserver_impl_c ImplT>
class AdcGenericNetServer
{
protected:
ImplT _impl;
public:
typedef ImplT server_impl_t;
using typename ImplT::server_ident_t;
template <typename... ImplCtorArgTs>
AdcGenericNetServer(ImplCtorArgTs&&... ctor_args) : _impl(std::make_unique<ImplT>(ctor_args)...)
{
}
virtual ~AdcGenericNetServer() = default;
virtual server_ident_t serverIdent() const
{
//
return _impl.serverIdent();
}
virtual void start()
{
//
_impl.start();
};
virtual void stop()
{
//
_impl.stop();
};
};
template <traits::adc_netserver_impl_c ImplT> template <traits::adc_netserver_impl_c ImplT>
class AdcNetServer class AdcNetServer
{ {
@ -159,6 +212,7 @@ public:
{ {
daemonizePrepare(); daemonizePrepare();
// reference implementation of forking for POSIX OSes
#ifdef FORK_EXISTS #ifdef FORK_EXISTS
// get TEMP directory in OS // get TEMP directory in OS
@ -204,6 +258,17 @@ public:
protected: protected:
// started sessions waek pointers
template <traits::adc_netserver_session_c SessionT>
static std::unordered_map<const AdcNetServer*, std::set<typename SessionT::weak_ptr_t>> _serverSessions;
template <traits::adc_netserver_session_c SessionT>
void startAsyncSession(const typename SessionT::shared_ptr_t& sess_ptr)
{
_serverSessions<SessionT>[this].insert(sess_ptr);
sess_ptr.start();
}
virtual void daemonizePrepare() virtual void daemonizePrepare()
{ {
// //

View File

@ -8,23 +8,19 @@ ABSTRACT DEVICE COMPONENTS LIBRARY
#include <chrono> #include <chrono>
#include <memory>
#include <utility> #include <utility>
namespace adc namespace adc
{ {
template <typename NetMessageT>
class AdcNetServiceAbstractImplementation;
template <typename NetMessageT, typename ImplT> template <typename NetMessageT, typename ImplT>
class AdcNetService class AdcNetService
{ {
protected: protected:
std::unique_ptr<ImplT> _implUptr; ImplT _impl;
public: public:
using typename ImplT::endpoint_t; using typename ImplT::endpoint_t;
@ -36,9 +32,11 @@ public:
static constexpr timeout_drtn_t defaultSendTimeout = std::chrono::seconds(5); static constexpr timeout_drtn_t defaultSendTimeout = std::chrono::seconds(5);
static constexpr timeout_drtn_t defaultRecvTimeout = std::chrono::seconds(5); static constexpr timeout_drtn_t defaultRecvTimeout = std::chrono::seconds(5);
AdcNetService(ImplT* impl) : _implUptr(impl) {} template <typename... ImplCtorArgTs>
AdcNetService(ImplCtorArgTs&&... ctor_args) : _impl(std::forward<ImplCtorArgTs>(ctor_args)...)
{
}
AdcNetService(std::unique_ptr<ImplT> impl) : _implUptr(std::move(impl)) {}
virtual ~AdcNetService() = default; virtual ~AdcNetService() = default;
@ -46,25 +44,22 @@ public:
/* asynchronuos operations */ /* asynchronuos operations */
// open connection // open connection
template <typename... ArgTs> auto asyncConnect(const endpoint_t& end_point, const timeout_drtn_t& timeout = defaultConnectTimeout)
auto asyncConnect(const endpoint_t& end_point,
const timeout_drtn_t& timeout = defaultConnectTimeout,
ArgTs&&... args)
{ {
return _implUptr->asyncConnect(end_point, timeout, std::forward<ArgTs>(args)...); return _impl.asyncConnect(end_point, timeout);
} }
template <typename... ArgTs> template <typename... ArgTs>
auto asyncSend(const NetMessageT& msg, const timeout_drtn_t& timeout = defaultSendTimeout, ArgTs&&... args) auto asyncSend(const NetMessageT& msg, const timeout_drtn_t& timeout = defaultSendTimeout, ArgTs&&... args)
{ {
return _implUptr->asyncSend(msg, timeout, std::forward<ArgTs>(args)...); return _impl.asyncSend(msg, timeout, std::forward<ArgTs>(args)...);
} }
template <typename... ArgTs> template <typename... ArgTs>
auto asyncReceive(const timeout_drtn_t& timeout = defaultRecvTimeout, ArgTs&&... args) auto asyncReceive(const timeout_drtn_t& timeout = defaultRecvTimeout, ArgTs&&... args)
{ {
return _implUptr->asyncReceive(timeout, std::forward<ArgTs>(args)...); return _impl.asyncReceive(timeout, std::forward<ArgTs>(args)...);
} }
@ -74,26 +69,26 @@ public:
template <typename... ArgTs> template <typename... ArgTs>
auto connect(const endpoint_t& endpoint, const timeout_drtn_t& timeout = defaultConnectTimeout, ArgTs&&... args) auto connect(const endpoint_t& endpoint, const timeout_drtn_t& timeout = defaultConnectTimeout, ArgTs&&... args)
{ {
return _implUptr->connect(endpoint, timeout, std::forward<ArgTs>(args)...); return _impl.connect(endpoint, timeout, std::forward<ArgTs>(args)...);
} }
template <typename... ArgTs> template <typename... ArgTs>
auto send(const NetMessageT& msg, const timeout_drtn_t& timeout = defaultSendTimeout, ArgTs&&... args) auto send(const NetMessageT& msg, const timeout_drtn_t& timeout = defaultSendTimeout, ArgTs&&... args)
{ {
return _implUptr->send(msg, timeout, std::forward<ArgTs>(args)...); return _impl.send(msg, timeout, std::forward<ArgTs>(args)...);
} }
template <typename... ArgTs> template <typename... ArgTs>
NetMessageT receive(const timeout_drtn_t& timeout = defaultRecvTimeout, ArgTs&&... args) NetMessageT receive(const timeout_drtn_t& timeout = defaultRecvTimeout, ArgTs&&... args)
{ {
return _implUptr->receive(timeout, std::forward<ArgTs>(args)...); return _impl.receive(timeout, std::forward<ArgTs>(args)...);
} }
template <typename... ArgTs> template <typename... ArgTs>
auto close(ArgTs&&... args) auto close(ArgTs&&... args)
{ {
return _implUptr->close(std::forward<ArgTs>(args)...); return _impl.close(std::forward<ArgTs>(args)...);
} }
}; };