#include "watchdog_thread.hpp" #include "connection.hpp" #include "irc_parse_thread.hpp" #include "write_irc.hpp" #include #include #include using namespace std::chrono_literals; namespace { struct WatchdogThread : std::enable_shared_from_this { WatchdogThread(Connection& connection) : connection_{connection} , timer_{connection.get_executor()} , tried_ping{false} { } Connection& connection_; boost::asio::steady_timer timer_; bool tried_ping; auto on_activity() -> void { tried_ping = false; timer_.expires_from_now(30s); } auto timeout_token() { return [weak = weak_from_this()](auto const& error) { if (not error) { if (auto self = weak.lock()) { self->on_timeout(); } } }; } auto on_timeout() -> void { if (tried_ping) { connection_.close(); } else { send_ping(connection_, "watchdog"); tried_ping = true; timer_.expires_from_now(30s); timer_.async_wait(timeout_token()); } } auto on_connect() -> void { on_activity(); timer_.async_wait(timeout_token()); } auto on_disconnect() -> void { timer_.cancel(); } }; } // namespace auto watchdog_thread(Connection& connection) -> void { auto const thread = std::make_shared(connection); connection.add_listener([thread](auto&) { thread->on_connect(); }); connection.add_listener([thread](auto&) { thread->on_disconnect(); }); connection.add_listener([thread](auto&) { thread->on_activity(); }); }