From a50120c3995b81958824968cff005ddda5a54458 Mon Sep 17 00:00:00 2001 From: Julian Brost Date: Wed, 28 Jul 2021 14:13:02 +0200 Subject: [PATCH 1/2] IcingaDB: start parent connection after children are initialized The loop in the connected callback of the parent connection uses m_Rcons which previously was only initialized after that connection was already started. --- lib/icingadb/icingadb.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/lib/icingadb/icingadb.cpp b/lib/icingadb/icingadb.cpp index a7eb3753e..7641d9bcd 100644 --- a/lib/icingadb/icingadb.cpp +++ b/lib/icingadb/icingadb.cpp @@ -68,6 +68,16 @@ void IcingaDB::Start(bool runtimeCreated) GetEnableTls(), GetInsecureNoverify(), GetCertPath(), GetKeyPath(), GetCaPath(), GetCrlPath(), GetTlsProtocolmin(), GetCipherList(), GetConnectTimeout(), GetDebugInfo()); + for (const Type::Ptr& type : GetTypes()) { + auto ctype (dynamic_cast(type.get())); + if (!ctype) + continue; + + m_Rcons[ctype] = new RedisConnection(GetHost(), GetPort(), GetPath(), GetPassword(), GetDbIndex(), + GetEnableTls(), GetInsecureNoverify(), GetCertPath(), GetKeyPath(), GetCaPath(), GetCrlPath(), + GetTlsProtocolmin(), GetCipherList(), GetConnectTimeout(), GetDebugInfo(), m_Rcon); + } + auto connectedCallback ([this](boost::asio::yield_context& yc) { m_WorkQueue.Enqueue([this]() { OnConnectedHandler(); }); }); @@ -82,16 +92,6 @@ void IcingaDB::Start(bool runtimeCreated) }); m_Rcon->Start(); - for (const Type::Ptr& type : GetTypes()) { - auto ctype (dynamic_cast(type.get())); - if (!ctype) - continue; - - m_Rcons[ctype] = new RedisConnection(GetHost(), GetPort(), GetPath(), GetPassword(), GetDbIndex(), - GetEnableTls(), GetInsecureNoverify(), GetCertPath(), GetKeyPath(), GetCaPath(), GetCrlPath(), - GetTlsProtocolmin(), GetCipherList(), GetConnectTimeout(), GetDebugInfo(), m_Rcon); - } - m_StatsTimer = new Timer(); m_StatsTimer->SetInterval(1); m_StatsTimer->OnTimerExpired.connect([this](const Timer * const&) { PublishStatsTimerHandler(); }); From 929ebd0f6c7f72b7d96c54c6592c8b7ebee85380 Mon Sep 17 00:00:00 2001 From: Julian Brost Date: Wed, 28 Jul 2021 14:28:21 +0200 Subject: [PATCH 2/2] IcingaDB: start initial sync after all child connections are established Icinga started the initial config sync right after the first Redis connection was established. If any other connections would take longer to connect than when it's first needed, queries were discarded. --- lib/icingadb/icingadb.cpp | 25 +++++++++++++++++-------- lib/icingadb/icingadb.hpp | 2 ++ 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/lib/icingadb/icingadb.cpp b/lib/icingadb/icingadb.cpp index 7641d9bcd..dec804f3d 100644 --- a/lib/icingadb/icingadb.cpp +++ b/lib/icingadb/icingadb.cpp @@ -73,22 +73,31 @@ void IcingaDB::Start(bool runtimeCreated) if (!ctype) continue; - m_Rcons[ctype] = new RedisConnection(GetHost(), GetPort(), GetPath(), GetPassword(), GetDbIndex(), + RedisConnection::Ptr con = new RedisConnection(GetHost(), GetPort(), GetPath(), GetPassword(), GetDbIndex(), GetEnableTls(), GetInsecureNoverify(), GetCertPath(), GetKeyPath(), GetCaPath(), GetCrlPath(), GetTlsProtocolmin(), GetCipherList(), GetConnectTimeout(), GetDebugInfo(), m_Rcon); + + con->SetConnectedCallback([this, con](boost::asio::yield_context& yc) { + con->SetConnectedCallback(nullptr); + + size_t pending = --m_PendingRcons; + Log(LogDebug, "IcingaDB") << pending << " pending child connections remaining"; + if (pending == 0) { + m_WorkQueue.Enqueue([this]() { OnConnectedHandler(); }); + } + }); + + m_Rcons[ctype] = std::move(con); } - auto connectedCallback ([this](boost::asio::yield_context& yc) { - m_WorkQueue.Enqueue([this]() { OnConnectedHandler(); }); - }); + m_PendingRcons = m_Rcons.size(); + + m_Rcon->SetConnectedCallback([this](boost::asio::yield_context& yc) { + m_Rcon->SetConnectedCallback(nullptr); - m_Rcon->SetConnectedCallback([this, connectedCallback](boost::asio::yield_context& yc) { for (auto& kv : m_Rcons) { kv.second->Start(); } - - m_Rcon->SetConnectedCallback(connectedCallback); - connectedCallback(yc); }); m_Rcon->Start(); diff --git a/lib/icingadb/icingadb.hpp b/lib/icingadb/icingadb.hpp index 2f7d0f98c..92949a089 100644 --- a/lib/icingadb/icingadb.hpp +++ b/lib/icingadb/icingadb.hpp @@ -13,6 +13,7 @@ #include "icinga/downtime.hpp" #include "remote/messageorigin.hpp" #include +#include #include #include #include @@ -169,6 +170,7 @@ private: RedisConnection::Ptr m_Rcon; std::unordered_map m_Rcons; + std::atomic_size_t m_PendingRcons; struct { DumpedGlobals CustomVar, ActionUrl, NotesUrl, IconImage;