mirror of
https://github.com/Icinga/icinga-powershell-framework.git
synced 2025-12-20 23:00:35 -05:00
Use a BlockingCollection to avoid busy loop in REST API threads
The former implementation had 5 threads permanently spinning fast (10ms sleep) while waiting for a REST connection to process. This causes higher load in general and it breaks systems where "Turn on PowerShell Script Block Logging policy" is enabled, because then each PS statement including Start-Sleep is logged - resulting in 500 event log entries per second. It's a suggested setting in some hardening guidelines. We can easily replace the Queue with a BlockingCollection backed by a ConcurrentQueue, which has the built-in feature to sleep until there are new items. Now the REST API threads consumes zero CPU time while waiting.
This commit is contained in:
parent
90e80c83bd
commit
d215cfd568
4 changed files with 8 additions and 17 deletions
|
|
@ -19,6 +19,7 @@ Released closed milestones can be found on [GitHub](https://github.com/Icinga/ic
|
||||||
* [#480](https://github.com/Icinga/icinga-powershell-framework/pull/480) Fixes service locking during Icinga Agent upgrade and ensures errors on service management are caught and printed with internal error handling
|
* [#480](https://github.com/Icinga/icinga-powershell-framework/pull/480) Fixes service locking during Icinga Agent upgrade and ensures errors on service management are caught and printed with internal error handling
|
||||||
* [#483](https://github.com/Icinga/icinga-powershell-framework/issues/483) Fixes REST-Api SSL certificate lookup from the Icinga Agent, in case a custom hostname was used or in certain domain environments were domain is not matching DNS domain
|
* [#483](https://github.com/Icinga/icinga-powershell-framework/issues/483) Fixes REST-Api SSL certificate lookup from the Icinga Agent, in case a custom hostname was used or in certain domain environments were domain is not matching DNS domain
|
||||||
* [#490](https://github.com/Icinga/icinga-powershell-framework/pull/490) Fixes the command `Uninstall-IcingaComponent` for the `service` component which is not doing anything
|
* [#490](https://github.com/Icinga/icinga-powershell-framework/pull/490) Fixes the command `Uninstall-IcingaComponent` for the `service` component which is not doing anything
|
||||||
|
* [#497](https://github.com/Icinga/icinga-powershell-framework/pull/497) Fixes loop sleep for idle REST-Api threads by replacing them with [BlockingCollection](https://docs.microsoft.com/en-us/dotnet/api/system.collections.concurrent.blockingcollection-1?view=net-6.0) [ConcurrentQueue](https://docs.microsoft.com/en-us/dotnet/api/system.collections.concurrent.concurrentqueue-1?view=net-6.0)
|
||||||
|
|
||||||
### Enhancements
|
### Enhancements
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -108,7 +108,7 @@ function New-IcingaForWindowsRESTApi()
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
$Global:Icinga.Public.Daemons.RESTApi.ApiRequests.$NextRESTApiThreadId.Enqueue($Connection);
|
$Global:Icinga.Public.Daemons.RESTApi.ApiRequests.$NextRESTApiThreadId.Add($Connection);
|
||||||
} catch {
|
} catch {
|
||||||
Write-IcingaEventMessage -Namespace 'RESTApi' -EvenId 2050 -ExceptionObject $_;
|
Write-IcingaEventMessage -Namespace 'RESTApi' -EvenId 2050 -ExceptionObject $_;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -75,8 +75,9 @@ function Start-IcingaWindowsRESTApi()
|
||||||
|
|
||||||
while ($ConcurrentThreads -gt 0) {
|
while ($ConcurrentThreads -gt 0) {
|
||||||
$ConcurrentThreads = $ConcurrentThreads - 1;
|
$ConcurrentThreads = $ConcurrentThreads - 1;
|
||||||
[System.Collections.Queue]$RESTThreadQueue = @();
|
$RESTThreadQueue = New-Object System.Collections.Concurrent.BlockingCollection[PSObject] `
|
||||||
$Global:Icinga.Public.Daemons.RESTApi.ApiRequests.Add($ThreadId, [System.Collections.Queue]::Synchronized($RESTThreadQueue));
|
-ArgumentList (New-Object System.Collections.Concurrent.ConcurrentQueue[PSObject]);
|
||||||
|
$Global:Icinga.Public.Daemons.RESTApi.ApiRequests.Add($ThreadId, $RESTThreadQueue);
|
||||||
Start-IcingaForWindowsRESTThread -ThreadId $ThreadId -RequireAuth:$RequireAuth;
|
Start-IcingaForWindowsRESTThread -ThreadId $ThreadId -RequireAuth:$RequireAuth;
|
||||||
$ThreadId += 1;
|
$ThreadId += 1;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,17 +16,8 @@ function New-IcingaForWindowsRESTThread()
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($Global:Icinga.Public.Daemons.RESTApi.ApiRequests.$ThreadId.Count -eq 0) {
|
# block sleeping until content available
|
||||||
Start-Sleep -Milliseconds 10;
|
$Connection = $Global:Icinga.Public.Daemons.RESTApi.ApiRequests.$ThreadId.Take();
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
$Connection = $Global:Icinga.Public.Daemons.RESTApi.ApiRequests.$ThreadId.Dequeue();
|
|
||||||
|
|
||||||
if ($null -eq $Connection) {
|
|
||||||
Start-Sleep -Milliseconds 10;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
# Read the received message from the stream by using our smart functions
|
# Read the received message from the stream by using our smart functions
|
||||||
[string]$RestMessage = Read-IcingaTCPStream -Client $Connection.Client -Stream $Connection.Stream;
|
[string]$RestMessage = Read-IcingaTCPStream -Client $Connection.Client -Stream $Connection.Stream;
|
||||||
|
|
@ -107,9 +98,7 @@ function New-IcingaForWindowsRESTThread()
|
||||||
|
|
||||||
# Finally close the clients connection as we are done here and
|
# Finally close the clients connection as we are done here and
|
||||||
# ensure this thread will close by simply leaving the function
|
# ensure this thread will close by simply leaving the function
|
||||||
if ($null -ne $Connection) {
|
|
||||||
Close-IcingaTCPConnection -Client $Connection.Client;
|
Close-IcingaTCPConnection -Client $Connection.Client;
|
||||||
}
|
|
||||||
|
|
||||||
# Force Icinga for Windows Garbage Collection
|
# Force Icinga for Windows Garbage Collection
|
||||||
Optimize-IcingaForWindowsMemory -ClearErrorStack;
|
Optimize-IcingaForWindowsMemory -ClearErrorStack;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue