mirror of
https://github.com/Icinga/icinga2.git
synced 2026-05-28 04:12:13 -04:00
Freeze perfdata arrays and remove locks in code using them
Since perfdata is set once when a check result is created and never changed again, locking this is unnecessary. This avoids components unnecessarily waiting on each other when processing perfdata. This fixes the locking cascade observed sometimes when the perfdata writer work queue blocks, where it extends to a lock on the entire check result eventually, affecting even more components.
This commit is contained in:
parent
6c73bb4af4
commit
80362fa2c8
14 changed files with 20 additions and 17 deletions
|
|
@ -33,3 +33,9 @@ double CheckResult::CalculateLatency() const
|
|||
|
||||
return latency;
|
||||
}
|
||||
|
||||
void CheckResult::SetPerformanceData(const Array::Ptr& value)
|
||||
{
|
||||
value->Freeze();
|
||||
ObjectImpl<CheckResult>::SetPerformanceData(value);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ public:
|
|||
|
||||
double CalculateExecutionTime() const;
|
||||
double CalculateLatency() const;
|
||||
void SetPerformanceData(const Array::Ptr& value);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -185,8 +185,6 @@ String PluginUtility::FormatPerfdata(const Array::Ptr& perfdata, bool normalize)
|
|||
|
||||
std::ostringstream result;
|
||||
|
||||
ObjectLock olock(perfdata);
|
||||
|
||||
bool first = true;
|
||||
for (const Value& pdv : perfdata) {
|
||||
if (!first)
|
||||
|
|
|
|||
|
|
@ -174,8 +174,6 @@ static void DoIfwNetIo(
|
|||
}
|
||||
|
||||
if (perfdata) {
|
||||
ObjectLock oLock (perfdata);
|
||||
|
||||
for (auto& pv : perfdata) {
|
||||
if (!pv.IsString()) {
|
||||
cr->SetOutput(
|
||||
|
|
|
|||
|
|
@ -202,7 +202,6 @@ void ElasticsearchWriter::AddCheckResult(const Dictionary::Ptr& fields, const Ch
|
|||
CheckCommand::Ptr checkCommand = checkable->GetCheckCommand();
|
||||
|
||||
if (perfdata) {
|
||||
ObjectLock olock(perfdata);
|
||||
for (const Value& val : perfdata) {
|
||||
PerfdataValue::Ptr pdv;
|
||||
|
||||
|
|
|
|||
|
|
@ -196,7 +196,6 @@ void GelfWriter::CheckResultHandler(const Checkable::Ptr& checkable, const Check
|
|||
Array::Ptr perfdata = cr->GetPerformanceData();
|
||||
|
||||
if (perfdata) {
|
||||
ObjectLock olock(perfdata);
|
||||
for (const Value& val : perfdata) {
|
||||
PerfdataValue::Ptr pdv;
|
||||
|
||||
|
|
|
|||
|
|
@ -224,7 +224,6 @@ void GraphiteWriter::SendPerfdata(const Checkable::Ptr& checkable, const String&
|
|||
|
||||
CheckCommand::Ptr checkCommand = checkable->GetCheckCommand();
|
||||
|
||||
ObjectLock olock(perfdata);
|
||||
for (const Value& val : perfdata) {
|
||||
PerfdataValue::Ptr pdv;
|
||||
|
||||
|
|
|
|||
|
|
@ -213,7 +213,6 @@ void InfluxdbCommonWriter::CheckResultHandler(const Checkable::Ptr& checkable, c
|
|||
double ts = cr->GetExecutionEnd();
|
||||
|
||||
if (Array::Ptr perfdata = cr->GetPerformanceData()) {
|
||||
ObjectLock olock(perfdata);
|
||||
for (const Value& val : perfdata) {
|
||||
PerfdataValue::Ptr pdv;
|
||||
|
||||
|
|
|
|||
|
|
@ -308,7 +308,6 @@ void OpenTsdbWriter::AddPerfdata(const Checkable::Ptr& checkable, const String&
|
|||
|
||||
CheckCommand::Ptr checkCommand = checkable->GetCheckCommand();
|
||||
|
||||
ObjectLock olock(perfdata);
|
||||
for (const Value& val : perfdata) {
|
||||
PerfdataValue::Ptr pdv;
|
||||
|
||||
|
|
|
|||
|
|
@ -181,7 +181,6 @@ void OTLPMetricsWriter::CheckResultHandler(const Checkable::Ptr& checkable, cons
|
|||
auto endTime = cr->GetExecutionEnd();
|
||||
|
||||
Array::Ptr perfdata = cr->GetPerformanceData();
|
||||
ObjectLock olock(perfdata);
|
||||
for (const Value& val : perfdata) {
|
||||
PerfdataValue::Ptr pdv;
|
||||
if (val.IsObjectType<PerfdataValue>()) {
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ BOOST_AUTO_TEST_CASE(quotes)
|
|||
BOOST_AUTO_TEST_CASE(multiple)
|
||||
{
|
||||
Array::Ptr pd = PluginUtility::SplitPerfdata("testA=123456 testB=123456");
|
||||
pd->Freeze();
|
||||
BOOST_CHECK_EQUAL(pd->GetLength(), 2);
|
||||
|
||||
String str = PluginUtility::FormatPerfdata(pd);
|
||||
|
|
@ -47,12 +48,14 @@ BOOST_AUTO_TEST_CASE(multiple)
|
|||
BOOST_AUTO_TEST_CASE(multiline)
|
||||
{
|
||||
Array::Ptr pd = PluginUtility::SplitPerfdata(" 'testA'=123456 'testB'=123456");
|
||||
pd->Freeze();
|
||||
BOOST_CHECK_EQUAL(pd->GetLength(), 2);
|
||||
|
||||
String str = PluginUtility::FormatPerfdata(pd);
|
||||
BOOST_CHECK_EQUAL(str, "testA=123456 testB=123456");
|
||||
|
||||
pd = PluginUtility::SplitPerfdata(" 'testA'=123456 \n'testB'=123456");
|
||||
pd->Freeze();
|
||||
BOOST_CHECK_EQUAL(pd->GetLength(), 2);
|
||||
|
||||
str = PluginUtility::FormatPerfdata(pd);
|
||||
|
|
@ -62,6 +65,7 @@ BOOST_AUTO_TEST_CASE(multiline)
|
|||
BOOST_AUTO_TEST_CASE(normalize)
|
||||
{
|
||||
Array::Ptr pd = PluginUtility::SplitPerfdata("testA=2m;3;4;1;5 testB=2foobar");
|
||||
pd->Freeze();
|
||||
BOOST_CHECK_EQUAL(pd->GetLength(), 2);
|
||||
|
||||
String str = PluginUtility::FormatPerfdata(pd, true);
|
||||
|
|
@ -333,6 +337,7 @@ BOOST_AUTO_TEST_CASE(ignore_warn_crit_ranges)
|
|||
BOOST_AUTO_TEST_CASE(empty_warn_crit_min_max)
|
||||
{
|
||||
Array::Ptr pd = PluginUtility::SplitPerfdata("testA=5;;7;1;9 testB=5;7;;1;9 testC=5;;;1;9 testD=2m;;;1 testE=5;;7;;");
|
||||
pd->Freeze();
|
||||
BOOST_CHECK_EQUAL(pd->GetLength(), 5);
|
||||
|
||||
String str = PluginUtility::FormatPerfdata(pd, true);
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ object Host "h1" {
|
|||
void ReceiveCheckResults(
|
||||
std::size_t num,
|
||||
ServiceState state,
|
||||
const std::function<void(const CheckResult::Ptr&)>& fn = {}
|
||||
const std::function<void(const CheckResult::Ptr&, const Array::Ptr&)>& fn = {}
|
||||
)
|
||||
{
|
||||
::ReceiveCheckResults(m_Host, num, state, fn);
|
||||
|
|
@ -95,8 +95,8 @@ object Host "h1" {
|
|||
auto start = std::chrono::steady_clock::now();
|
||||
std::size_t unchangedCount = 0;
|
||||
while(true){
|
||||
ReceiveCheckResults(10, ServiceCritical, [&](const CheckResult::Ptr& cr) {
|
||||
cr->GetPerformanceData()->Add(new PerfdataValue{GetRandomString("", 4096), 1});
|
||||
ReceiveCheckResults(10, ServiceCritical, [&](const CheckResult::Ptr&, const Array::Ptr& perfdata) {
|
||||
perfdata->Add(new PerfdataValue{GetRandomString("", 4096), 1});
|
||||
});
|
||||
|
||||
if (std::chrono::steady_clock::now() - start >= timeout) {
|
||||
|
|
|
|||
|
|
@ -93,7 +93,7 @@ void ReceiveCheckResults(
|
|||
const icinga::Checkable::Ptr& host,
|
||||
std::size_t num,
|
||||
icinga::ServiceState state,
|
||||
const std::function<void(const icinga::CheckResult::Ptr&)>& fn
|
||||
const std::function<void(const icinga::CheckResult::Ptr&, const icinga::Array::Ptr&)>& fn
|
||||
)
|
||||
{
|
||||
using namespace icinga;
|
||||
|
|
@ -114,12 +114,13 @@ void ReceiveCheckResults(
|
|||
|
||||
Array::Ptr perfData = new Array;
|
||||
perfData->Add(new PerfdataValue{"dummy", 42});
|
||||
cr->SetPerformanceData(perfData);
|
||||
|
||||
if (fn) {
|
||||
fn(cr);
|
||||
fn(cr, perfData);
|
||||
}
|
||||
|
||||
cr->SetPerformanceData(perfData);
|
||||
|
||||
BOOST_REQUIRE(host->ProcessCheckResult(cr, wg) == Checkable::ProcessingResult::Ok);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,5 +33,5 @@ void ReceiveCheckResults(
|
|||
const icinga::Checkable::Ptr& host,
|
||||
std::size_t num,
|
||||
icinga::ServiceState state,
|
||||
const std::function<void(const icinga::CheckResult::Ptr&)>& fn = {}
|
||||
const std::function<void(const icinga::CheckResult::Ptr&, const icinga::Array::Ptr&)>& fn = {}
|
||||
);
|
||||
|
|
|
|||
Loading…
Reference in a new issue