Skip to content

Commit 223b7d9

Browse files
author
rhamlett_microsoft
committed
Added 502.3 response for timed out requests and logging for requests exceeding timeout threshold.
1 parent d50939a commit 223b7d9

File tree

7 files changed

+54
-1
lines changed

7 files changed

+54
-1
lines changed

src/PerfProblemSimulator/Controllers/AdminController.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using Microsoft.AspNetCore.Http.Timeouts;
12
using Microsoft.AspNetCore.Mvc;
23
using PerfProblemSimulator.Models;
34
using PerfProblemSimulator.Services;
@@ -25,6 +26,7 @@ namespace PerfProblemSimulator.Controllers;
2526
/// </remarks>
2627
[ApiController]
2728
[Route("api/[controller]")]
29+
[RequestTimeout("NoTimeout")] // Admin endpoints must always respond
2830
public class AdminController : ControllerBase
2931
{
3032
private readonly ISimulationTracker _simulationTracker;

src/PerfProblemSimulator/Controllers/HealthController.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using Microsoft.AspNetCore.Http.Timeouts;
12
using Microsoft.AspNetCore.Mvc;
23
using PerfProblemSimulator.Services;
34

@@ -23,6 +24,7 @@ namespace PerfProblemSimulator.Controllers;
2324
[ApiController]
2425
[Route("api/[controller]")]
2526
[Produces("application/json")]
27+
[RequestTimeout("NoTimeout")] // Health endpoints must always respond, never timeout
2628
public class HealthController : ControllerBase
2729
{
2830
private readonly ISimulationTracker _simulationTracker;

src/PerfProblemSimulator/Controllers/MetricsController.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using Microsoft.AspNetCore.Http.Timeouts;
12
using Microsoft.AspNetCore.Mvc;
23
using PerfProblemSimulator.Models;
34
using PerfProblemSimulator.Services;
@@ -25,6 +26,7 @@ namespace PerfProblemSimulator.Controllers;
2526
/// </remarks>
2627
[ApiController]
2728
[Route("api/[controller]")]
29+
[RequestTimeout("NoTimeout")] // Metrics endpoints must always respond
2830
public class MetricsController : ControllerBase
2931
{
3032
private readonly IMetricsCollector _metricsCollector;

src/PerfProblemSimulator/Controllers/SlowRequestController.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using Microsoft.AspNetCore.Http.Timeouts;
12
using Microsoft.AspNetCore.Mvc;
23
using PerfProblemSimulator.Models;
34
using PerfProblemSimulator.Services;
@@ -34,6 +35,7 @@ namespace PerfProblemSimulator.Controllers;
3435
[Route("api/[controller]")]
3536
[Produces("application/json")]
3637
[Tags("Slow Request Simulation")]
38+
[RequestTimeout("SlowRequest")] // Extended 120s timeout for intentionally slow requests
3739
public class SlowRequestController : ControllerBase
3840
{
3941
private readonly ISlowRequestService _slowRequestService;

src/PerfProblemSimulator/Program.cs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,37 @@
169169
});
170170
});
171171

172+
// -----------------------------------------------------------------------------
173+
// Request Timeouts (Kestrel)
174+
// -----------------------------------------------------------------------------
175+
// Add request timeouts for local development to match IIS behavior (web.config).
176+
// This ensures slow requests timeout after 30 seconds, consistent with the UI threshold.
177+
// Educational Note: In Azure App Service, the web.config requestTimeout handles this.
178+
// For local Kestrel development, we use the RequestTimeouts middleware instead.
179+
builder.Services.AddRequestTimeouts(options =>
180+
{
181+
// Default 30-second timeout for all endpoints (matches web.config and UI threshold)
182+
options.DefaultPolicy = new Microsoft.AspNetCore.Http.Timeouts.RequestTimeoutPolicy
183+
{
184+
Timeout = TimeSpan.FromSeconds(30),
185+
TimeoutStatusCode = StatusCodes.Status504GatewayTimeout
186+
};
187+
188+
// Extended timeout for slow request simulation endpoint
189+
// This endpoint intentionally runs 20-35s requests, so it needs more time
190+
options.AddPolicy("SlowRequest", new Microsoft.AspNetCore.Http.Timeouts.RequestTimeoutPolicy
191+
{
192+
Timeout = TimeSpan.FromSeconds(120),
193+
TimeoutStatusCode = StatusCodes.Status504GatewayTimeout
194+
});
195+
196+
// No timeout for health/admin endpoints - they must always respond
197+
options.AddPolicy("NoTimeout", new Microsoft.AspNetCore.Http.Timeouts.RequestTimeoutPolicy
198+
{
199+
Timeout = null // Disable timeout
200+
});
201+
});
202+
172203
var app = builder.Build();
173204

174205
// -----------------------------------------------------------------------------
@@ -195,6 +226,10 @@
195226
// CORS must be called before UseRouting
196227
app.UseCors();
197228

229+
// Request timeouts middleware (Kestrel) - matches web.config requestTimeout for IIS
230+
// Educational Note: This must be placed before UseRouting so timeouts apply to all requests.
231+
app.UseRequestTimeouts();
232+
198233
// Serve static files from wwwroot (for the SPA dashboard)
199234
app.UseDefaultFiles(); // Enables default document (index.html)
200235
app.UseStaticFiles();

src/PerfProblemSimulator/web.config

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@
1010
1111
When hosting model is "outofprocess", the app runs in a separate dotnet.exe process,
1212
and Azure Crash Monitoring (which monitors w3wp.exe) won't capture crashes.
13+
14+
requestTimeout="00:00:30" - 30 second timeout matches the UI threshold.
15+
Requests exceeding this will fail with HTTP 502.3 (Bad Gateway - timeout).
16+
This demonstrates realistic timeout behavior for educational purposes.
1317
-->
1418
<handlers>
1519
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2" resourceType="Unspecified" />
@@ -18,7 +22,8 @@
1822
arguments=".\PerfProblemSimulator.dll"
1923
stdoutLogEnabled="false"
2024
stdoutLogFile=".\logs\stdout"
21-
hostingModel="inprocess">
25+
hostingModel="inprocess"
26+
requestTimeout="00:00:30">
2227
<environmentVariables>
2328
<!-- Enable detailed errors for diagnostics -->
2429
<environmentVariable name="ASPNETCORE_DETAILEDERRORS" value="true" />

src/PerfProblemSimulator/wwwroot/js/dashboard.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -558,6 +558,11 @@ function handleSlowRequestLatency(data) {
558558
msg += ` [Queue Time: ${queueSec}s]`;
559559
}
560560
logEvent('error', msg);
561+
} else if (isTimeout) {
562+
// Request completed but exceeded the 30s timeout threshold
563+
// In IIS with requestTimeout="00:00:30", this would have been terminated with HTTP 502.3
564+
let msg = `⏱️ Slow request #${data.requestNumber} TIMEOUT: ${durationSec}s exceeded 30s threshold (${scenario}) [Queue Time: ${queueSec}s]`;
565+
logEvent('error', msg);
561566
} else {
562567
let msg = `🐌 Slow request #${data.requestNumber} completed: ${durationSec}s (${scenario}) [Queue Time: ${queueSec}s]`;
563568
logEvent('warning', msg);

0 commit comments

Comments
 (0)