Icinga DB: HMSET the same fields only once

This commit is contained in:
Alexander A. Klimov 2021-02-24 13:37:36 +01:00
parent aa4f53009e
commit ed57d31400
3 changed files with 61 additions and 8 deletions

View File

@ -155,6 +155,13 @@ void IcingaDB::UpdateAllConfigObjects()
DeleteKeys(globalKeys, Prio::Config);
DeleteKeys({"icinga:nextupdate:host", "icinga:nextupdate:service"}, Prio::CheckResult);
Defer resetDumpedGlobals ([this]() {
m_DumpedGlobals.CustomVar.Reset();
m_DumpedGlobals.ActionUrl.Reset();
m_DumpedGlobals.NotesUrl.Reset();
m_DumpedGlobals.IconImage.Reset();
});
upq.ParallelFor(types, [this](const TypePair& type) {
String lcType = type.second;
@ -405,8 +412,10 @@ void IcingaDB::InsertObjectDependencies(const ConfigObject::Ptr& object, const S
varsArray->Reserve(vars->GetLength());
for (auto& kv : vars) {
if (runtimeUpdate || m_DumpedGlobals.CustomVar.IsNew(kv.first)) {
allCvs.emplace_back(kv.first);
allCvs.emplace_back(JsonEncode(kv.second));
}
if (runtimeUpdate) {
publishes["icinga:config:update:customvar"].emplace_back(kv.first);
@ -432,8 +441,13 @@ void IcingaDB::InsertObjectDependencies(const ConfigObject::Ptr& object, const S
String iconImage = checkable->GetIconImage();
if (!actionUrl.IsEmpty()) {
auto& actionUrls (hMSets[m_PrefixConfigObject + "action_url"]);
actionUrls.emplace_back(HashValue(new Array({env, actionUrl})));
auto id (HashValue(new Array({env, actionUrl})));
if (runtimeUpdate || m_DumpedGlobals.ActionUrl.IsNew(id)) {
actionUrls.emplace_back(std::move(id));
actionUrls.emplace_back(JsonEncode(new Dictionary({{"environment_id", envId}, {"action_url", actionUrl}})));
}
if (runtimeUpdate) {
publishes["icinga:config:update:action_url"].emplace_back(actionUrls.at(actionUrls.size() - 2u));
@ -441,8 +455,13 @@ void IcingaDB::InsertObjectDependencies(const ConfigObject::Ptr& object, const S
}
if (!notesUrl.IsEmpty()) {
auto& notesUrls (hMSets[m_PrefixConfigObject + "notes_url"]);
notesUrls.emplace_back(HashValue(new Array({env, notesUrl})));
auto id (HashValue(new Array({env, notesUrl})));
if (runtimeUpdate || m_DumpedGlobals.NotesUrl.IsNew(id)) {
notesUrls.emplace_back(std::move(id));
notesUrls.emplace_back(JsonEncode(new Dictionary({{"environment_id", envId}, {"notes_url", notesUrl}})));
}
if (runtimeUpdate) {
publishes["icinga:config:update:notes_url"].emplace_back(notesUrls.at(notesUrls.size() - 2u));
@ -450,8 +469,13 @@ void IcingaDB::InsertObjectDependencies(const ConfigObject::Ptr& object, const S
}
if (!iconImage.IsEmpty()) {
auto& iconImages (hMSets[m_PrefixConfigObject + "icon_image"]);
iconImages.emplace_back(HashValue(new Array({env, iconImage})));
auto id (HashValue(new Array({env, iconImage})));
if (runtimeUpdate || m_DumpedGlobals.IconImage.IsNew(id)) {
iconImages.emplace_back(std::move(id));
iconImages.emplace_back(JsonEncode(new Dictionary({{"environment_id", envId}, {"icon_image", iconImage}})));
}
if (runtimeUpdate) {
publishes["icinga:config:update:icon_image"].emplace_back(iconImages.at(iconImages.size() - 2u));

View File

@ -147,3 +147,15 @@ void IcingaDB::AssertOnWorkQueue()
{
ASSERT(m_WorkQueue.IsWorkerThread());
}
void IcingaDB::DumpedGlobals::Reset()
{
std::lock_guard<std::mutex> l (m_Mutex);
m_Ids.clear();
}
bool IcingaDB::DumpedGlobals::IsNew(const String& id)
{
std::lock_guard<std::mutex> l (m_Mutex);
return m_Ids.emplace(id).second;
}

View File

@ -13,6 +13,8 @@
#include "icinga/downtime.hpp"
#include "remote/messageorigin.hpp"
#include <memory>
#include <mutex>
#include <set>
#include <utility>
namespace icinga
@ -35,6 +37,17 @@ public:
virtual void Stop(bool runtimeRemoved) override;
private:
class DumpedGlobals
{
public:
void Reset();
bool IsNew(const String& id);
private:
std::set<String> m_Ids;
std::mutex m_Mutex;
};
void OnConnectedHandler();
void PublishStatsTimerHandler();
@ -143,6 +156,10 @@ private:
bool m_ConfigDumpDone;
RedisConnection::Ptr m_Rcon;
struct {
DumpedGlobals CustomVar, ActionUrl, NotesUrl, IconImage;
} m_DumpedGlobals;
};
}