Merge pull request #180 from Icinga:feature/split_thread_content_local_usage_only

Feature: Ensure thread results are separated from each other by default

In case multitple background daemons are running and executing check plugins, it can happen that results overlap from one thread to another. A CPU check might then include information from another service check for example.

We fix this by locking each check result data into an own thread, preventing other threads from accessing the data.
This commit is contained in:
Lord Hepipud 2021-02-22 16:56:20 +01:00 committed by GitHub
commit 9a1c187e90
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 24 additions and 43 deletions

View file

@ -7,12 +7,13 @@ documentation before upgrading to a new release.
Released closed milestones can be found on [GitHub](https://github.com/Icinga/icinga-powershell-framework/milestones?state=closed).
## 1.4.0 (pending)
## 1.4.0 (2021-03-02)
[Issue and PRs](https://github.com/Icinga/icinga-powershell-framework/milestone/11?closed=1)
### Enhancements
* [#180](https://github.com/Icinga/icinga-powershell-framework/pull/180) Ensure check data are separated from each thread and not accessible from one thread to another to prevent conflicting results
* [#193](https://github.com/Icinga/icinga-powershell-framework/pull/193) Adds optional support for adding milliseconds to `Get-IcingaUnixTime` with the `-Milliseconds` argument for more detailed time comparison
* [#198](https://github.com/Icinga/icinga-powershell-framework/pull/198) Adds support to flush the content of the Icinga Agent API directory with a single Cmdlet `Clear-IcingaAgentApiDirectory`
* [#203](https://github.com/Icinga/icinga-powershell-framework/pull/203) Removes experimental state of the Icinga PowerShell Framework code caching and adds docs on how to use the feature

View file

@ -17,24 +17,12 @@
function Get-IcingaCheckSchedulerPerfData()
{
if ($null -eq $IcingaDaemonData) {
if ($null -eq $global:Icinga) {
return $null;
}
if ($IcingaDaemonData.ContainsKey('IcingaThreadContent') -eq $FALSE) {
return $null;
}
if ($IcingaDaemonData.IcingaThreadContent.ContainsKey('Scheduler') -eq $FALSE) {
return $null;
}
if ($IcingaDaemonData.IcingaThreadContent.Scheduler.ContainsKey('PluginPerfData') -eq $FALSE) {
return $null;
}
$PerfData = $IcingaDaemonData.IcingaThreadContent.Scheduler.PluginPerfData;
$IcingaDaemonData.IcingaThreadContent.Scheduler.PluginPerfData = @();
$PerfData = $global:Icinga.PerfData;
$global:Icinga.PerfData = @();
return $PerfData;
}

View file

@ -17,24 +17,12 @@
function Get-IcingaCheckSchedulerPluginOutput()
{
if ($null -eq $IcingaDaemonData) {
if ($null -eq $global:Icinga) {
return $null;
}
if ($IcingaDaemonData.ContainsKey('IcingaThreadContent') -eq $FALSE) {
return $null;
}
if ($IcingaDaemonData.IcingaThreadContent.ContainsKey('Scheduler') -eq $FALSE) {
return $null;
}
if ($IcingaDaemonData.IcingaThreadContent.Scheduler.ContainsKey('PluginCache') -eq $FALSE) {
return $null;
}
$CheckResult = [string]::Join("`r`n", $IcingaDaemonData.IcingaThreadContent.Scheduler.PluginCache);
$IcingaDaemonData.IcingaThreadContent.Scheduler.PluginCache = @();
$CheckResult = [string]::Join("`r`n", $global:Icinga.CheckResults);
$global:Icinga.CheckResults = @();
return $CheckResult;
}

View file

@ -1,8 +1,12 @@
function New-IcingaCheckSchedulerEnvironment()
{
# Legacy code
$IcingaDaemonData.IcingaThreadContent.Add('Scheduler', @{ });
if ($IcingaDaemonData.IcingaThreadContent['Scheduler'].ContainsKey('PluginCache') -eq $FALSE) {
$IcingaDaemonData.IcingaThreadContent['Scheduler'].Add('PluginCache', @());
$IcingaDaemonData.IcingaThreadContent['Scheduler'].Add('PluginPerfData', @());
if ($null -eq $global:Icinga) {
$global:Icinga = @{};
}
$global:Icinga.Add('CheckResults', @());
$global:Icinga.Add('PerfData', @());
}

View file

@ -101,6 +101,9 @@ function Start-IcingaServiceCheckTask()
try {
& $CheckCommand @Arguments | Out-Null;
Get-IcingaCheckSchedulerPerfData | Out-Null;
Get-IcingaCheckSchedulerPluginOutput | Out-Null;
$UnixTime = Get-IcingaUnixTime;
foreach ($result in $IcingaDaemonData.BackgroundDaemon.ServiceCheckScheduler[$CheckCommand]['results'].Keys) {

View file

@ -7,8 +7,7 @@ function Write-IcingaPluginOutput()
if ($global:IcingaDaemonData.FrameworkRunningAsDaemon -eq $FALSE) {
Write-IcingaConsolePlain $Output;
} else {
if ($global:IcingaDaemonData.IcingaThreadContent.ContainsKey('Scheduler')) {
$global:IcingaDaemonData.IcingaThreadContent['Scheduler']['PluginCache'] += $Output;
}
# New behavior with local thread separated results
$global:Icinga.CheckResults += $Output;
}
}

View file

@ -45,9 +45,8 @@ function Get-IcingaPluginPerfDataContent()
$cachedresult = (New-IcingaPerformanceDataEntry -PerfDataObject $data -Label $SearchEntry -Value $checkresult.Value);
if ($AsObject) {
if ($global:IcingaDaemonData.IcingaThreadContent.ContainsKey('Scheduler')) {
$global:IcingaDaemonData.IcingaThreadContent['Scheduler']['PluginPerfData'] += $cachedresult;
}
# New behavior with local thread separated results
$global:Icinga.PerfData += $cachedresult;
}
$PerfDataOutput += $cachedresult;
}
@ -56,9 +55,8 @@ function Get-IcingaPluginPerfDataContent()
$compiledPerfData = (New-IcingaPerformanceDataEntry $data);
if ($AsObject) {
if ($global:IcingaDaemonData.IcingaThreadContent.ContainsKey('Scheduler')) {
$global:IcingaDaemonData.IcingaThreadContent['Scheduler']['PluginPerfData'] += $compiledPerfData;
}
# New behavior with local thread separated results
$global:Icinga.PerfData += $compiledPerfData;
}
$PerfDataOutput += $compiledPerfData;
}