public void ReportAndFixIfNeeded(ILog log) { var state = ThreadPoolUtility.GetPoolState(); if (state.UsedWorkerThreads < state.MinWorkerThreads && state.UsedIocpThreads < state.MinIocpThreads) { return; } var currentTimestamp = DateTime.UtcNow; lock (syncObject) { if (currentTimestamp - lastReportTimestamp < minReportInterval) { return; } lastReportTimestamp = currentTimestamp; } log.Warn( "Looks like you're kinda low on ThreadPool, buddy. " + $"Workers: {state.UsedWorkerThreads}/{state.MinWorkerThreads}/{state.MaxWorkerThreads}, " + $"IOCP: {state.UsedIocpThreads}/{state.MinIocpThreads}/{state.MaxIocpThreads} (busy/min/max)."); var currentMultiplier = Math.Min(state.MinWorkerThreads / Environment.ProcessorCount, state.MinIocpThreads / Environment.ProcessorCount); if (currentMultiplier < 128) { log.Info("I will configure ThreadPool for you, buddy!"); ThreadPoolUtility.Setup(log); } }
public SystemMetrics GetSystemMetrics() { var threadPoolState = ThreadPoolUtility.GetPoolState(); var sample = requestCounters.NextSample(); return(new SystemMetrics { UsedThreads = threadPoolState.UsedThreads, UsedIocpThreads = threadPoolState.UsedIocpThreads, WorkingRequests = sample.WorkingRequests, RequestsPerSecond = sample.AverageRps }); }
public static void ReportAndFixIfNeeded(ILog log) { var state = ThreadPoolUtility.GetPoolState(); if (state.UsedWorkerThreads < state.MinWorkerThreads && state.UsedIocpThreads < state.MinIocpThreads) { return; } var currentTimestamp = DateTime.UtcNow; lock (syncObject) { if (currentTimestamp - lastReportTimestamp < MinReportInterval) { return; } lastReportTimestamp = currentTimestamp; } log = log.ForContext(typeof(ThreadPoolMonitor)); log.Warn( "Looks like you're kinda low on ThreadPool, buddy. " + "Workers: {UsedWorkerThreads}/{MinWorkerThreads}, " + "IOCP: {UsedIocpThreads}/{MinIocpThreads} (busy/min).", state.UsedWorkerThreads, state.MinWorkerThreads, state.UsedIocpThreads, state.MinIocpThreads); var currentMultiplier = Math.Min( state.MinWorkerThreads / Environment.ProcessorCount, state.MinIocpThreads / Environment.ProcessorCount); if (currentMultiplier < TargetMultiplier) { log.Info("I will configure ThreadPool for you, buddy!"); ThreadPoolUtility.Setup(TargetMultiplier); var newState = ThreadPoolUtility.GetPoolState(); log.Info("New min worker threads = {MinWorkerThreads}", newState.MinWorkerThreads); log.Info("New min IOCP threads = {MinIocpThreads}", newState.MinIocpThreads); } }
public Task <HealthCheckResult> CheckAsync(CancellationToken cancellationToken) { var state = ThreadPoolUtility.GetPoolState(); if (state.UsedWorkerThreads >= state.MinWorkerThreads) { return(Task.FromResult(HealthCheckResult.Degraded($"Worker threads in thread pool are exhausted: {state.UsedWorkerThreads}/{state.MinWorkerThreads} (used/min)."))); } if (state.UsedIocpThreads >= state.MinIocpThreads) { return(Task.FromResult(HealthCheckResult.Degraded($"IOCP threads in thread pool are exhausted: {state.UsedIocpThreads}/{state.MinIocpThreads} (used/min)."))); } return(Task.FromResult(HealthCheckResult.Healthy())); }
private void LogThreadPoolSettings() { var state = ThreadPoolUtility.GetPoolState(); log.Info("Thread pool configuration: {MinWorkerThreads} min workers, {MinIOCPThreads} min IOCP.", state.MinWorkerThreads, state.MinIocpThreads); }