94 lines
1.9 KiB
C++
94 lines
1.9 KiB
C++
#include "watchdog_thread.hpp"
|
|
|
|
#include "connection.hpp"
|
|
#include "irc_parse_thread.hpp"
|
|
#include "write_irc.hpp"
|
|
|
|
#include <boost/asio/steady_timer.hpp>
|
|
|
|
#include <chrono>
|
|
#include <memory>
|
|
|
|
using namespace std::chrono_literals;
|
|
|
|
namespace {
|
|
|
|
struct WatchdogThread : std::enable_shared_from_this<WatchdogThread>
|
|
{
|
|
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<WatchdogThread>(connection);
|
|
connection.add_listener<ConnectEvent>([thread](auto&)
|
|
{
|
|
thread->on_connect();
|
|
});
|
|
connection.add_listener<DisconnectEvent>([thread](auto&)
|
|
{
|
|
thread->on_disconnect();
|
|
});
|
|
connection.add_listener<IrcMsgEvent>([thread](auto&)
|
|
{
|
|
thread->on_activity();
|
|
});
|
|
}
|