Created
September 20, 2020 12:45
-
-
Save martinrayenglish/b084bdb7efb2779f63fcb7c7b60b84b0 to your computer and use it in GitHub Desktop.
Sitecore Thread Pool Size Monitor
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using Sitecore.Abstractions; | |
using Sitecore.Framework.Conditions; | |
using System; | |
using System.Threading; | |
namespace Sitecore.Analytics | |
{ | |
internal class ThreadPoolSizeMonitor : IThreadPoolSizeMonitor, IDisposable | |
{ | |
private readonly int _accelerationRate; | |
private readonly int _decelerationRate; | |
private readonly TimeSpan _updateInterval; | |
private readonly BaseLog _log; | |
private bool _disposed; | |
public ThreadPoolSizeMonitor( | |
int accelerationRate, | |
int decelerationRate, | |
TimeSpan updateInterval, | |
BaseLog log) | |
{ | |
Condition.Requires<int>(accelerationRate, nameof (accelerationRate)).IsGreaterThan(0); | |
Condition.Requires<int>(decelerationRate, nameof (decelerationRate)).IsGreaterThan(0); | |
Condition.Requires<BaseLog>(log, nameof (log)).IsNotNull<BaseLog>(); | |
this._accelerationRate = accelerationRate; | |
this._decelerationRate = decelerationRate; | |
this._updateInterval = updateInterval; | |
this._log = log; | |
this._log.Info(string.Format("Initialized ThreadPoolSizeMonitor with parameters accelerationRate: {0}, decelerationRate: {1}, updateInterval: {2}", (object) this._accelerationRate, (object) this._decelerationRate, (object) this._updateInterval), (object) this); | |
} | |
public void Start() | |
{ | |
this._log.Info("Start thread pool size monitor in the background", (object) this); | |
new Thread(new ThreadStart(this.Monitor)) | |
{ | |
IsBackground = true | |
}.Start(); | |
} | |
public void Stop() | |
{ | |
this.Dispose(); | |
} | |
public void Dispose() | |
{ | |
this._disposed = true; | |
} | |
private void Monitor() | |
{ | |
while (!this._disposed) | |
{ | |
try | |
{ | |
int workerThreads1; | |
ThreadPool.GetAvailableThreads(out workerThreads1, out int _); | |
int workerThreads2; | |
int completionPortThreads; | |
ThreadPool.GetMinThreads(out workerThreads2, out completionPortThreads); | |
int workerThreads3; | |
ThreadPool.GetMaxThreads(out workerThreads3, out int _); | |
int num1 = workerThreads3 - workerThreads1; | |
int processorCount = System.Environment.ProcessorCount; | |
int num2 = num1 >= processorCount ? this._accelerationRate * (int) Math.Round((double) num1 / (double) this._accelerationRate) + this._accelerationRate : processorCount; | |
if (num2 >= workerThreads2 && num2 < workerThreads3 - 10) | |
{ | |
if (num2 != workerThreads2) | |
{ | |
workerThreads2 = num2; | |
ThreadPool.SetMinThreads(workerThreads2, completionPortThreads); | |
this._log.Debug(string.Format("Increased min threads to {0}", (object) workerThreads2), (object) this); | |
} | |
} | |
else if (num2 < workerThreads2) | |
{ | |
workerThreads2 -= this._decelerationRate; | |
ThreadPool.SetMinThreads(workerThreads2, completionPortThreads); | |
this._log.Debug(string.Format("Cooling down. {0} threads are active", (object) workerThreads2), (object) this); | |
} | |
this._log.Debug(string.Format("Min threads: {0}, Active threads: {1}.", (object) workerThreads2, (object) (workerThreads3 - workerThreads1)), (object) this); | |
} | |
catch (Exception ex) | |
{ | |
this._log.Error("Exception occured in ThreadPoolSizeMonitor", ex, (object) this); | |
} | |
Thread.Sleep(this._updateInterval); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment