Skip to content

Commit

Permalink
Close server connections and shutdown coroutines immediately on disco…
Browse files Browse the repository at this point in the history
…nnect
  • Loading branch information
Al2Klimov committed Jun 5, 2019
1 parent b0cdad0 commit a3f04be
Show file tree
Hide file tree
Showing 5 changed files with 34 additions and 13 deletions.
16 changes: 12 additions & 4 deletions lib/remote/httpserverconnection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ using namespace icinga;
auto const l_ServerHeader ("Icinga/" + Application::GetAppVersion());

HttpServerConnection::HttpServerConnection(const String& identity, bool authenticated, const std::shared_ptr<AsioTlsStream>& stream)
: m_Stream(stream), m_Seen(Utility::GetTime()), m_IoStrand(stream->get_io_service()), m_ShuttingDown(false), m_HasStartedStreaming(false)
: m_Stream(stream), m_Seen(Utility::GetTime()), m_IoStrand(stream->get_io_service()), m_ShuttingDown(false), m_HasStartedStreaming(false),
m_CheckLivenessTimer(stream->get_io_service())
{
if (authenticated) {
m_ApiUser = ApiUser::GetByClientCN(identity);
Expand Down Expand Up @@ -80,6 +81,13 @@ void HttpServerConnection::Disconnect()
} catch (...) {
}

try {
m_Stream->lowest_layer().cancel();
} catch (...) {
}

m_CheckLivenessTimer.cancel();

auto listener (ApiListener::GetInstance());

if (listener) {
Expand Down Expand Up @@ -529,11 +537,11 @@ void HttpServerConnection::ProcessMessages(boost::asio::yield_context yc)

void HttpServerConnection::CheckLiveness(boost::asio::yield_context yc)
{
boost::asio::deadline_timer timer (m_Stream->get_io_service());
boost::system::error_code ec;

for (;;) {
timer.expires_from_now(boost::posix_time::seconds(5));
timer.async_wait(yc);
m_CheckLivenessTimer.expires_from_now(boost::posix_time::seconds(5));
m_CheckLivenessTimer.async_wait(yc[ec]);

if (m_ShuttingDown) {
break;
Expand Down
2 changes: 2 additions & 0 deletions lib/remote/httpserverconnection.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include "base/string.hpp"
#include "base/tlsstream.hpp"
#include <memory>
#include <boost/asio/deadline_timer.hpp>
#include <boost/asio/io_service_strand.hpp>
#include <boost/asio/spawn.hpp>

Expand Down Expand Up @@ -39,6 +40,7 @@ class HttpServerConnection final : public Object
boost::asio::io_service::strand m_IoStrand;
bool m_ShuttingDown;
bool m_HasStartedStreaming;
boost::asio::deadline_timer m_CheckLivenessTimer;

void ProcessMessages(boost::asio::yield_context yc);
void CheckLiveness(boost::asio::yield_context yc);
Expand Down
8 changes: 4 additions & 4 deletions lib/remote/jsonrpcconnection-heartbeat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,21 @@
#include "base/configtype.hpp"
#include "base/logger.hpp"
#include "base/utility.hpp"
#include <boost/asio/deadline_timer.hpp>
#include <boost/asio/spawn.hpp>
#include <boost/date_time/posix_time/posix_time_duration.hpp>
#include <boost/system/system_error.hpp>

using namespace icinga;

REGISTER_APIFUNCTION(Heartbeat, event, &JsonRpcConnection::HeartbeatAPIHandler);

void JsonRpcConnection::HandleAndWriteHeartbeats(boost::asio::yield_context yc)
{
boost::asio::deadline_timer timer (m_Stream->get_io_service());
boost::system::error_code ec;

for (;;) {
timer.expires_from_now(boost::posix_time::seconds(10));
timer.async_wait(yc);
m_HeartbeatTimer.expires_from_now(boost::posix_time::seconds(10));
m_HeartbeatTimer.async_wait(yc[ec]);

if (m_ShuttingDown) {
break;
Expand Down
19 changes: 14 additions & 5 deletions lib/remote/jsonrpcconnection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@
#include "base/tlsstream.hpp"
#include <memory>
#include <utility>
#include <boost/asio/deadline_timer.hpp>
#include <boost/asio/spawn.hpp>
#include <boost/date_time/posix_time/posix_time_duration.hpp>
#include <boost/system/system_error.hpp>
#include <boost/thread/once.hpp>

using namespace icinga;
Expand All @@ -32,7 +32,8 @@ JsonRpcConnection::JsonRpcConnection(const String& identity, bool authenticated,
const std::shared_ptr<AsioTlsStream>& stream, ConnectionRole role)
: m_Identity(identity), m_Authenticated(authenticated), m_Stream(stream),
m_Role(role), m_Timestamp(Utility::GetTime()), m_Seen(Utility::GetTime()), m_NextHeartbeat(0), m_IoStrand(stream->get_io_service()),
m_OutgoingMessagesQueued(stream->get_io_service()), m_WriterDone(stream->get_io_service()), m_ShuttingDown(false)
m_OutgoingMessagesQueued(stream->get_io_service()), m_WriterDone(stream->get_io_service()), m_ShuttingDown(false),
m_CheckLivenessTimer(stream->get_io_service()), m_HeartbeatTimer(stream->get_io_service())
{
if (authenticated)
m_Endpoint = Endpoint::GetByName(identity);
Expand Down Expand Up @@ -206,6 +207,14 @@ void JsonRpcConnection::Disconnect()
} catch (...) {
}

try {
m_Stream->lowest_layer().cancel();
} catch (...) {
}

m_CheckLivenessTimer.cancel();
m_HeartbeatTimer.cancel();

CpuBoundWork removeClient (yc);

if (m_Endpoint) {
Expand Down Expand Up @@ -310,11 +319,11 @@ Value SetLogPositionHandler(const MessageOrigin::Ptr& origin, const Dictionary::

void JsonRpcConnection::CheckLiveness(boost::asio::yield_context yc)
{
boost::asio::deadline_timer timer (m_Stream->get_io_service());
boost::system::error_code ec;

for (;;) {
timer.expires_from_now(boost::posix_time::seconds(30));
timer.async_wait(yc);
m_CheckLivenessTimer.expires_from_now(boost::posix_time::seconds(30));
m_CheckLivenessTimer.async_wait(yc[ec]);

if (m_ShuttingDown) {
break;
Expand Down
2 changes: 2 additions & 0 deletions lib/remote/jsonrpcconnection.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "base/workqueue.hpp"
#include <memory>
#include <vector>
#include <boost/asio/deadline_timer.hpp>
#include <boost/asio/io_service_strand.hpp>
#include <boost/asio/spawn.hpp>

Expand Down Expand Up @@ -77,6 +78,7 @@ class JsonRpcConnection final : public Object
AsioConditionVariable m_OutgoingMessagesQueued;
AsioConditionVariable m_WriterDone;
bool m_ShuttingDown;
boost::asio::deadline_timer m_CheckLivenessTimer, m_HeartbeatTimer;

void HandleIncomingMessages(boost::asio::yield_context yc);
void WriteOutgoingMessages(boost::asio::yield_context yc);
Expand Down

0 comments on commit a3f04be

Please sign in to comment.