diff --git a/lib/remote/httpserverconnection.cpp b/lib/remote/httpserverconnection.cpp index fde33fdcc..39fa2d79d 100644 --- a/lib/remote/httpserverconnection.cpp +++ b/lib/remote/httpserverconnection.cpp @@ -18,7 +18,6 @@ #include "base/timer.hpp" #include "base/tlsstream.hpp" #include "base/utility.hpp" -#include #include #include #include @@ -41,7 +40,7 @@ HttpServerConnection::HttpServerConnection(const WaitGroup::Ptr& waitGroup, cons } HttpServerConnection::HttpServerConnection(const WaitGroup::Ptr& waitGroup, const String& identity, bool authenticated, const Shared::Ptr& stream, boost::asio::io_context& io) - : m_WaitGroup(waitGroup), m_Stream(stream), m_Seen(Utility::GetTime()), m_IoStrand(io), m_ShuttingDown(false), m_ConnectionReusable(true), m_CheckLivenessTimer(io) + : m_WaitGroup(waitGroup), m_Stream(stream), m_IoStrand(io), m_ShuttingDown(false), m_ConnectionReusable(true), m_CheckLivenessTimer(io) { if (authenticated) { m_ApiUser = ApiUser::GetByClientCN(identity); @@ -152,9 +151,9 @@ bool HttpServerConnection::Disconnected() return m_ShuttingDown; } -void HttpServerConnection::SetLivenessTimeout(double seconds) +void HttpServerConnection::SetLivenessTimeout(std::chrono::milliseconds timeout) { - m_LivenessTimeout = seconds; + m_LivenessTimeout = timeout; } static inline @@ -458,7 +457,7 @@ void HttpServerConnection::ProcessMessages(boost::asio::yield_context yc) beast::flat_buffer buf; while (m_WaitGroup->IsLockable()) { - m_Seen = Utility::GetTime(); + m_Seen = ch::steady_clock::now(); HttpRequest request(m_Stream); HttpResponse response(m_Stream, this); @@ -472,7 +471,7 @@ void HttpServerConnection::ProcessMessages(boost::asio::yield_context yc) break; } - m_Seen = Utility::GetTime(); + m_Seen = ch::steady_clock::now(); auto start (ch::steady_clock::now()); { @@ -524,7 +523,7 @@ void HttpServerConnection::ProcessMessages(boost::asio::yield_context yc) break; } - m_Seen = std::numeric_limits::max(); + m_Seen = ch::steady_clock::time_point::max(); ProcessRequest(request, response, m_WaitGroup, cpuBoundWorkTime, yc); @@ -549,17 +548,19 @@ void HttpServerConnection::CheckLiveness(boost::asio::yield_context yc) for (;;) { // Wait for the half of the liveness timeout to give the connection some leeway to do other work. // But never wait longer than 5 seconds to ensure timely shutdowns. - auto sleepTime = std::min(5ll*1000, static_cast(m_LivenessTimeout * 500)); - m_CheckLivenessTimer.expires_from_now(boost::posix_time::milliseconds(sleepTime)); + auto sleepTime = std::min(5000ms, m_LivenessTimeout / 2); + m_CheckLivenessTimer.expires_from_now(boost::posix_time::milliseconds(sleepTime.count())); m_CheckLivenessTimer.async_wait(yc[ec]); if (m_ShuttingDown) { break; } - if (m_Seen < Utility::GetTime() - m_LivenessTimeout) { + if (m_LivenessTimeout < std::chrono::steady_clock::now() - m_Seen) { Log(LogInformation, "HttpServerConnection") - << "No messages for HTTP connection have been received in the last 10 seconds."; + << "No messages for HTTP connection have been received in the last " + << std::chrono::duration_cast(m_LivenessTimeout).count() + << " seconds, disconnecting (from " << m_PeerAddress << ")."; Disconnect(yc); break; diff --git a/lib/remote/httpserverconnection.hpp b/lib/remote/httpserverconnection.hpp index 63f1ad6f7..4436897f1 100644 --- a/lib/remote/httpserverconnection.hpp +++ b/lib/remote/httpserverconnection.hpp @@ -12,10 +12,13 @@ #include #include #include +#include namespace icinga { +using namespace std::chrono_literals; + /** * An API client connection. * @@ -34,22 +37,22 @@ public: bool Disconnected(); /** - * Sets the liveness timeout in seconds. + * Sets the liveness timeout. * * If we don't receive any data from the client in this time frame, we consider the connection * dead and close it. The default is 10 seconds. This function should only be used for unit tests * to speed them up. * - * @param seconds The timeout in seconds. + * @param timeout The timeout duration. */ - void SetLivenessTimeout(double seconds); + void SetLivenessTimeout(std::chrono::milliseconds timeout); private: WaitGroup::Ptr m_WaitGroup; ApiUser::Ptr m_ApiUser; Shared::Ptr m_Stream; - double m_Seen; - double m_LivenessTimeout{10.0}; // The liveness timeout in seconds. @see SetLivenessTimeout() for details. + std::chrono::steady_clock::time_point m_Seen{std::chrono::steady_clock::now()}; + std::chrono::milliseconds m_LivenessTimeout{10s}; String m_PeerAddress; boost::asio::io_context::strand m_IoStrand; bool m_ShuttingDown; diff --git a/test/remote-httpserverconnection.cpp b/test/remote-httpserverconnection.cpp index 7596ae325..ac0f895b8 100644 --- a/test/remote-httpserverconnection.cpp +++ b/test/remote-httpserverconnection.cpp @@ -45,7 +45,7 @@ struct HttpServerConnectionFixture : TlsStreamFixture, ConfigurationCacheDirFixt user->Register(); } - void SetupHttpServerConnection(bool authenticated, double livenessTimeout = 10.0) + void SetupHttpServerConnection(bool authenticated, std::chrono::milliseconds livenessTimeout = std::chrono::milliseconds(10000)) { String identity = authenticated ? "client" : "invalid"; m_Connection = new HttpServerConnection(m_WaitGroup, identity, authenticated, server); @@ -553,11 +553,11 @@ BOOST_AUTO_TEST_CASE(handler_throw_streaming) BOOST_AUTO_TEST_CASE(liveness_disconnect) { - SetupHttpServerConnection(false, .300); // 300ms liveness timeout is more than enough! + SetupHttpServerConnection(false, std::chrono::milliseconds(300)); // 300ms liveness timeout is more than enough! BOOST_REQUIRE(AssertServerDisconnected(std::chrono::milliseconds(450))); // Give some leeway to Asio's timers BOOST_REQUIRE(ExpectLogPattern("HTTP client disconnected .*")); - BOOST_REQUIRE(ExpectLogPattern("No messages for HTTP connection have been received in the last 10 seconds.")); + BOOST_REQUIRE(ExpectLogPattern("No messages for HTTP connection have been received in the last \\d+ seconds, disconnecting .*")); BOOST_REQUIRE(Shutdown(client)); }