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);
            }
        }
Exemple #4
0
        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()));
        }
Exemple #5
0
        private void LogThreadPoolSettings()
        {
            var state = ThreadPoolUtility.GetPoolState();

            log.Info("Thread pool configuration: {MinWorkerThreads} min workers, {MinIOCPThreads} min IOCP.", state.MinWorkerThreads, state.MinIocpThreads);
        }