diff --git a/net/adc_device_netserver.h b/net/adc_device_netserver.h index 737cc57..5c1e413 100644 --- a/net/adc_device_netserver.h +++ b/net/adc_device_netserver.h @@ -153,16 +153,11 @@ protected: CmdIdDeserialT&& cmd_id_deser_func = {}) : _id(id) { - // _get_id = [dev_ptr, wrapper = traits::adc_pf_wrapper(std::forward(id_ser_func))]() { - // auto id = std::get<0>(wrapper)(dev_ptr->ident()); - // return serialized_t{id.begin(), id.end()}; - // }; - _get_attr = [dev_ptr, wrapper = traits::adc_pf_wrapper(std::forward(attr_id_deser_func)), this](const auto& attr_name) mutable { auto attr_id = std::get<0>(wrapper)(attr_name); - // auto& attr = (*dev_ptr)[attr_id]; - auto& attr = dev_ptr->operator[](attr_id); + auto& attr = (*dev_ptr)[attr_id]; + // auto& attr = dev_ptr->operator[](attr_id); auto val = attr.serialize(); return val; }; @@ -214,16 +209,28 @@ public: public: typedef SessionIdentT netsession_ident_t; typedef NetServiceT netservice_t; - typedef AdcDeviceNetServer* netsession_ctx_t; + // typedef AdcDeviceNetServer* netsession_ctx_t; + + struct netsession_ctx_t { + AdcDeviceNetServer* serverPtr; + std::chrono::milliseconds recvTimeout; + std::chrono::milliseconds sendTimeout; + }; typedef std::vector message_t; - Session(const netsession_ident_t& id, netservice_t srv, AdcDeviceNetServer* srv_ptr) + // Session(const netsession_ident_t& id, netservice_t srv, AdcDeviceNetServer* srv_ptr) + Session(const netsession_ident_t& id, netservice_t srv, netsession_ctx_t ctx) : _ident(id), _netService(std::move(srv)), - _serverPtr(srv_ptr), - _bindDevice(srv_ptr->_devices.size() ? &srv_ptr->_devices.begin()->second - : &AdcDeviceNetServer::nullDevice) + // _serverPtr(srv_ptr), + // _bindDevice(srv_ptr->_devices.size() ? &srv_ptr->_devices.begin()->second + // : &AdcDeviceNetServer::nullDevice) + _serverPtr(ctx.serverPtr), + _bindDevice(ctx.serverPtr->_devices.size() ? &ctx.serverPtr->_devices.begin()->second + : &AdcDeviceNetServer::nullDevice), + _recvTimeout(ctx.recvTimeout), + _sendTimeout(ctx.sendTimeout) { } @@ -239,6 +246,8 @@ public: _netService.asyncReceive( [self, this](netservice_t::async_callback_err_t ec, message_t msg) { if (ec) { + _serverPtr->errorMessage(std::string("asyncReceive operation completed with") + + netservice_t::formatError(ec)); stop(); } else { auto msg_sptr = std::make_shared(std::move(msg)); @@ -251,6 +260,8 @@ public: *msg_sptr, [self, msg_sptr, this](netservice_t::async_callback_err_t ec) { if (ec) { + _serverPtr->errorMessage(std::string("asyncSend operation completed with") + + netservice_t::formatError(ec)); stop(); } else { start(); @@ -273,8 +284,8 @@ public: AdcDeviceNetServer* _serverPtr; AdcDeviceNetServer::DeviceWrapper* _bindDevice; - std::chrono::duration _recvTimeout = std::chrono::seconds(3600); - std::chrono::duration _sendTimeout = std::chrono::seconds(5); + std::chrono::milliseconds _recvTimeout = std::chrono::hours(12); + std::chrono::milliseconds _sendTimeout = std::chrono::seconds(5); void processMessage(auto& msg) { diff --git a/net/adc_netserver.h b/net/adc_netserver.h index ada6daa..6b70274 100644 --- a/net/adc_netserver.h +++ b/net/adc_netserver.h @@ -353,10 +353,13 @@ protected: _isListening[this][id] = true; doAccept(acceptor, std::move(id), std::move(sess_ctx)); } else { + errorMessage(SessionT::netservice_t::formatError(ec)); _isListening[this][id] = false; } }); } + + virtual void errorMessage(const std::string&) = 0; }; diff --git a/net/adc_netserver_spdlog.h b/net/adc_netserver_spdlog.h index 9b13b0a..51b689d 100644 --- a/net/adc_netserver_spdlog.h +++ b/net/adc_netserver_spdlog.h @@ -57,6 +57,15 @@ public: logDebug("Use logger with ", this->loggerInfo()); } + + virtual ~AdcGenericNetServerSpdlog() + { + this->logMethodCalling(__PRETTY_FUNCTION__); + + logDebug("Deleting ADC-library generic network server with ID = [{}] (ADDR = {})", _serverID, + this->_thisAddress); + } + virtual server_ident_t ident() const { this->logMethodCalling(__PRETTY_FUNCTION__); @@ -99,153 +108,19 @@ public: } + void daemonize() + requires std::derived_from + { + this->logMethodCalling(__PRETTY_FUNCTION__); -protected: + logInfo("Daemonizing server ..."); + + ServerT::daemonize(); + + logInfo("The server was daemonized"); + } }; -// template -// class AdcNetServerSessionSpdlogDecorator : public AdcSpdlogGenericMarkDecorator -// { -// protected: -// using base_t = AdcSpdlogGenericMarkDecorator; - -// std::string _sessionID; - -// public: -// using base_t::logDebug; -// using base_t::logInfo; -// using base_t::logMethodCalling; - -// // using SessionT::sessionIdent; -// using typename SessionT::session_ident_t; - -// static_assert(traits::formattable, "NETWORK SESSION IDENT TYPE MUST BE A FORMATTABLE ONE!!!"); - -// template -// AdcNetServerSessionSpdlogDecorator(std::shared_ptr logger, ImplCtorArgTs&&... ctor_args) -// : base_t("ADC NETSERVER SESSION", logger, std::forward(ctor_args)...) -// { -// logMethodCalling(__PRETTY_FUNCTION__); - -// fmt::format_to(std::back_inserter(_sessionID), "{}", SessionT::sessionIdent()); - -// this->setPattern(base_t::constructPattern(_sessionID)); - -// logDebug("Creating network server session with ID = [{}] (ADDR = {})", _sessionID, this->_thisAddress); -// logDebug("Use logger with ", this->loggerInfo()); -// } - -// virtual ~AdcNetServerSessionSpdlogDecorator() -// { -// logMethodCalling(__PRETTY_FUNCTION__); - -// logDebug("Deleting network server session with ID = [{}] (ADDR = {})", _sessionID, this->_thisAddress); -// }; - -// virtual session_ident_t sessionIdent() const override -// { -// logMethodCalling(__PRETTY_FUNCTION__); - -// return SessionT::sessionIdent(); -// }; - -// virtual void start() override -// { -// logMethodCalling(__PRETTY_FUNCTION__); - -// logInfo("Starting network server session with ID = [{}]", _sessionID); - -// SessionT::start(); - -// logInfo("Network server session [{}] is started", _sessionID); -// }; - -// virtual void stop() override -// { -// logMethodCalling(__PRETTY_FUNCTION__); - -// logInfo("Stopping network server session with ID = [{}]", _sessionID); - -// SessionT::stop(); - -// logInfo("Network server session [{}] is stopped", _sessionID); -// }; -// }; - - - -// template -// class AdcNetServerSpdlogDecorator : public AdcSpdlogGenericMarkDecorator -// { -// protected: -// using base_t = AdcSpdlogGenericMarkDecorator; - -// std::string _serverID; - -// public: -// using base_t::logCritical; -// using base_t::logDebug; -// using base_t::logError; -// using base_t::logInfo; -// using base_t::logMsg; -// using base_t::logWarn; - -// using typename ServerT::server_ident_t; - -// static_assert(traits::formattable, "NETWORK SERVER IDENT TYPE MUST BE A FORMATTABLE ONE!!!"); - -// template -// AdcNetServerSpdlogDecorator(std::shared_ptr logger, ImplCtorArgTs&&... ctor_args) -// : base_t("ADC NETSERVER", logger, std::forward(ctor_args)...) -// { -// this->logMethodCalling(__PRETTY_FUNCTION__); - -// fmt::format_to(std::back_inserter(_serverID), "{}", ServerT::serverIdent()); - -// this->setPattern(base_t::constructPattern(_serverID)); - -// logDebug("Creating network server with ID = [{}] (ADDR = {})", _serverID, this->_thisAddress); -// logDebug("Use logger with ", this->loggerInfo()); -// } - - -// virtual ~AdcNetServerSpdlogDecorator() -// { -// this->logMethodCalling(__PRETTY_FUNCTION__); - -// logDebug("Deleting network server with ID = [{}] (ADDR = {})", _serverID, this->_thisAddress); -// } - - -// virtual server_ident_t serverIdent() const -// { -// this->logMethodCalling(__PRETTY_FUNCTION__); - -// return ServerT::serverIdent(); -// } - -// virtual void start() -// { -// this->logMethodCalling(__PRETTY_FUNCTION__); - -// logInfo("Starting network server"); - -// ServerT::start(); - -// logInfo("Network server is started"); -// }; - -// virtual void stop() -// { -// this->logMethodCalling(__PRETTY_FUNCTION__); - -// logInfo("Stopping network server ..."); - -// ServerT::stop(); - -// logInfo("Network server is stopped"); -// }; -// }; } // namespace adc::spdlog diff --git a/net/asio/adc_device_netserver_asio.h b/net/asio/adc_device_netserver_asio.h index 971bc15..9dd4ace 100644 --- a/net/asio/adc_device_netserver_asio.h +++ b/net/asio/adc_device_netserver_asio.h @@ -50,19 +50,25 @@ public: if (endpoint.isTCP()) { asio::ip::tcp::endpoint ept(asio::ip::make_address(endpoint.host()), endpoint.port()); using srv_t = AdcNetServiceASIO; - base_t::template start>("TCP", this, _ioContext, ept); + // base_t::template start>("TCP", this, _ioContext, ept); + base_t::template start>("TCP", {this, _sessionRecvTimeout, _sessionSendTimeout}, _ioContext, + ept); #ifdef USE_OPENSSL_WITH_ASIO } else if (endpoint.isTLS()) { asio::ip::tcp::endpoint ept(asio::ip::make_address(endpoint.host()), endpoint.port()); using srv_t = AdcNetServiceASIOTLS; - base_t::template start>("TLS", this, _ioContext, ept, std::move(tls_context), - tls_verify_mode); + // base_t::template start>("TLS", this, _ioContext, ept, std::move(tls_context), + // tls_verify_mode); + base_t::template start>("TLS", {this, _sessionRecvTimeout, _sessionSendTimeout}, _ioContext, + ept, std::move(tls_context), tls_verify_mode); #endif } else if (endpoint.isLocal()) { if (endpoint.isLocalStream()) { asio::local::stream_protocol::endpoint ept(endpoint.template path()); using srv_t = AdcNetServiceASIO; - base_t::template start>("LOCAL STREAM", this, _ioContext, ept); + // base_t::template start>("LOCAL STREAM", this, _ioContext, ept); + base_t::template start>("LOCAL STREAM", {this, _sessionRecvTimeout, _sessionSendTimeout}, + _ioContext, ept); // } else if (endpoint.isLocalDatagram()) { // asio::local::datagram_protocol::endpoint ept(endpoint.template path()); // using srv_t = AdcNetServiceASIO; @@ -70,7 +76,9 @@ public: } else if (endpoint.isLocalSeqpacket()) { asio::local::seq_packet_protocol::endpoint ept(endpoint.template path()); using srv_t = AdcNetServiceASIO; - base_t::template start>("LOCAL SEQPACK", this, _ioContext, ept); + // base_t::template start>("LOCAL SEQPACK", this, _ioContext, ept); + base_t::template start>( + "LOCAL SEQPACK", {this, _sessionRecvTimeout, _sessionSendTimeout}, _ioContext, ept); } } else { throw std::system_error(std::make_error_code(std::errc::protocol_not_supported)); @@ -104,11 +112,24 @@ public: }); } + template + requires(std::convertible_to && + std::convertible_to) + void setSessionTimeouts(const RT& recv_timeout, const ST& send_timeout) + { + _sessionRecvTimeout = recv_timeout; + _sessionSendTimeout = send_timeout; + } + protected: asio::io_context& _ioContext; asio::signal_set _stopSignal, _restartSignal; + std::chrono::milliseconds _sessionRecvTimeout = std::chrono::hours(12); + std::chrono::milliseconds _sessionSendTimeout = std::chrono::seconds(5); + + // demonizing ASIO-related methods virtual void daemonizePrepare() { diff --git a/net/asio/adc_netservice_asio.h b/net/asio/adc_netservice_asio.h index 25bc0ea..604a378 100644 --- a/net/asio/adc_netservice_asio.h +++ b/net/asio/adc_netservice_asio.h @@ -757,6 +757,15 @@ public: return _shutdownType; } + + template + static void formatError(std::error_code err, + OutputItT out_iter, + FormatT fmt = "{} (Err category: {}) (Err msg: {})") + { + std::format_to(out_iter, fmt, err.value(), err.category().name(), err.message()); + } + protected: static constexpr netservice_ident_t _ident = std::derived_from>