File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change 123123// Educational Note: This service demonstrates how thread pool starvation affects request
124124// processing time. It runs on a dedicated thread (not the thread pool) to ensure it can
125125// always measure latency, even during severe starvation conditions.
126- builder . Services . AddHttpClient ( "LatencyProbe" ) ;
126+ builder . Services . AddHttpClient ( "LatencyProbe" )
127+ . ConfigurePrimaryHttpMessageHandler ( ( ) => new SocketsHttpHandler
128+ {
129+ // Disable connection pooling to avoid socket reuse issues on localhost
130+ PooledConnectionLifetime = TimeSpan . Zero ,
131+ PooledConnectionIdleTimeout = TimeSpan . Zero ,
132+ // Allow connections to localhost
133+ ConnectTimeout = TimeSpan . FromSeconds ( 5 )
134+ } ) ;
127135builder . Services . AddHostedService < LatencyProbeService > ( ) ;
128136
129137// -----------------------------------------------------------------------------
Original file line number Diff line number Diff line change @@ -126,17 +126,26 @@ private void ProbeLoop(object? state)
126126 {
127127 var cancellationToken = ( CancellationToken ) state ! ;
128128
129- // Wait a moment for the server to fully start
130- Thread . Sleep ( 2000 ) ;
129+ // Wait for the server to fully start and accept connections
130+ Thread . Sleep ( 5000 ) ;
131131
132132 // Get the base URL (may need to refresh after server starts)
133133 var baseUrl = _baseUrl ?? GetProbeBaseUrl ( ) ;
134134 _logger . LogInformation ( "Latency probe targeting: {BaseUrl}/api/health/probe" , baseUrl ) ;
135135
136- // Create HttpClient with timeout
137- using var httpClient = _httpClientFactory . CreateClient ( "LatencyProbe" ) ;
138- httpClient . BaseAddress = new Uri ( baseUrl ) ;
139- httpClient . Timeout = TimeSpan . FromMilliseconds ( RequestTimeoutMs ) ;
136+ // Create a handler that doesn't pool connections to avoid socket reuse issues
137+ var handler = new SocketsHttpHandler
138+ {
139+ PooledConnectionLifetime = TimeSpan . Zero ,
140+ PooledConnectionIdleTimeout = TimeSpan . Zero ,
141+ ConnectTimeout = TimeSpan . FromSeconds ( 5 )
142+ } ;
143+
144+ using var httpClient = new HttpClient ( handler )
145+ {
146+ BaseAddress = new Uri ( baseUrl ) ,
147+ Timeout = TimeSpan . FromMilliseconds ( RequestTimeoutMs )
148+ } ;
140149
141150 while ( ! cancellationToken . IsCancellationRequested )
142151 {
Original file line number Diff line number Diff line change 44 < meta charset ="UTF-8 ">
55 < meta name ="viewport " content ="width=device-width, initial-scale=1.0 ">
66 < title > Performance Problem Simulator - Documentation</ title >
7+ < link rel ="icon " type ="image/svg+xml " href ="/favicon.svg ">
78 < link rel ="stylesheet " href ="css/dashboard.css ">
89 < style >
910 /* Documentation-specific styles */
Original file line number Diff line number Diff line change 44 < meta charset ="UTF-8 ">
55 < meta name ="viewport " content ="width=device-width, initial-scale=1.0 ">
66 < title > Performance Problem Simulator - Dashboard</ title >
7+ < link rel ="icon " type ="image/svg+xml " href ="/favicon.svg ">
78 < link rel ="stylesheet " href ="css/dashboard.css ">
89 <!-- Chart.js for real-time graphs -->
910 < script src ="https://cdn.jsdelivr.net/npm/chart.js@4.4.1/dist/chart.umd.min.js "> </ script >
Original file line number Diff line number Diff line change @@ -424,7 +424,11 @@ function updateCharts() {
424424 * This shows the impact of thread pool starvation on request processing time.
425425 */
426426function handleLatencyUpdate ( measurement ) {
427- console . log ( 'Received latency update:' , measurement ) ;
427+ // Only log errors or significant latency, not every update
428+ if ( measurement . isError || measurement . isTimeout || measurement . latencyMs > 500 ) {
429+ console . log ( 'Latency update:' , measurement ) ;
430+ }
431+
428432 const timestamp = new Date ( measurement . timestamp ) ;
429433 const latencyMs = measurement . latencyMs ;
430434 const isTimeout = measurement . isTimeout ;
You can’t perform that action at this time.
0 commit comments