Files
michaelschiemer/docs/middleware-robustness.md
Michael Schiemer 55a330b223 Enable Discovery debug logging for production troubleshooting
- Add DISCOVERY_LOG_LEVEL=debug
- Add DISCOVERY_SHOW_PROGRESS=true
- Temporary changes for debugging InitializerProcessor fixes on production
2025-08-11 20:13:26 +02:00

131 lines
5.3 KiB
Markdown

# Middleware System Robustness Improvements
This document describes the improvements made to the middleware system to make it more robust and provides guidelines for developing robust middlewares.
## Improvements Implemented
### 1. Exception Handling
The `ExceptionHandlingMiddleware` has been positioned as the first middleware in the chain to ensure it can catch exceptions from all other middlewares. This ensures that any exception thrown by a middleware will be properly handled and converted to an appropriate HTTP response.
### 2. Timeout Mechanism
A timeout mechanism has been added to the `MiddlewareInvoker` to prevent long-running middlewares from blocking requests indefinitely. If a middleware exceeds its configured timeout, a `MiddlewareTimeoutException` is thrown, which is then caught by the `ExceptionHandlingMiddleware`.
Timeouts can be configured:
- Globally via the `MIDDLEWARE_TIMEOUT` environment variable (default: 5 seconds)
- Per middleware class via the `$middlewareTimeouts` parameter in the `MiddlewareInvoker` constructor
### 3. Circuit Breaker Pattern
A circuit breaker pattern has been implemented to prevent repeatedly failing middlewares from being executed. The `MiddlewareCircuitBreaker` class uses the existing `CircuitBreaker` module to track middleware failures and temporarily disable middlewares that fail too often.
The circuit breaker has three states:
- **Closed**: Normal operation, middleware is allowed to execute
- **Open**: Too many failures, middleware is not allowed to execute
- **Half-Open**: After a cooldown period, allows one execution to test if the middleware is working again
The integration with the existing `CircuitBreaker` module provides several benefits:
- Consistent circuit breaker behavior across the application
- Shared configuration and monitoring capabilities
- Improved reliability through a well-tested implementation
### 4. Enhanced Logging and Monitoring
A metrics collection system has been implemented to track middleware execution performance and failures. The `MiddlewareMetricsCollector` class collects and reports metrics about middleware execution, including:
- Execution time (min, max, average, total)
- Success/failure counts and rates
- Error types and counts
- Last execution time
## Guidelines for Developing Robust Middlewares
### 1. Error Handling
- Always catch and handle exceptions specific to your middleware's functionality
- Let unexpected exceptions propagate to be caught by the `ExceptionHandlingMiddleware`
- Use appropriate HTTP status codes for different error conditions
### 2. Performance Considerations
- Keep middleware execution time as short as possible
- For long-running operations, consider using asynchronous processing
- Be aware of the configured timeout for your middleware
### 3. Resource Management
- Properly manage resources (file handles, database connections, etc.)
- Use try-finally blocks to ensure resources are released even if an exception occurs
- Be mindful of memory usage, especially when processing large requests
### 4. Middleware Dependencies
- Keep dependencies between middlewares to a minimum
- Document required middleware execution order in code comments
- Use the `MiddlewarePriorityAttribute` to specify the desired execution order
### 5. Testing
- Write unit tests for your middleware
- Test both success and failure scenarios
- Test with various input data, including edge cases
- Test timeout scenarios
## Monitoring and Troubleshooting
### Metrics
The middleware system now collects detailed metrics about middleware execution. These metrics can be accessed via the `MiddlewareMetricsCollector` class:
```php
// Get metrics for a specific middleware
$metrics = $metricsCollector->getMetrics(MyMiddleware::class);
// Get metrics for all middlewares
$allMetrics = $metricsCollector->getAllMetrics();
```
### Circuit Breaker Status
You can interact with the circuit breaker for middlewares using the following methods:
```php
// Check if a middleware is allowed to execute
$isAllowed = $circuitBreaker->isAllowed(MyMiddleware::class);
// Get the current state of the circuit for a middleware
$state = $circuitBreaker->getState(MyMiddleware::class); // Returns CircuitState enum
// Reset the circuit for a middleware
$circuitBreaker->reset(MyMiddleware::class);
// Get metrics for a middleware
$metrics = $circuitBreaker->getMetrics(MyMiddleware::class);
```
The circuit breaker state can be one of the following:
- `CircuitState::CLOSED`: Normal operation, middleware is allowed to execute
- `CircuitState::OPEN`: Too many failures, middleware is not allowed to execute
- `CircuitState::HALF_OPEN`: Testing if the middleware is working again
### Logging
The middleware system logs detailed information about middleware execution, including:
- Start and end of middleware execution
- Execution time
- Errors and exceptions
- Circuit breaker state changes
Check the application logs for entries with the middleware name to troubleshoot issues.
## Conclusion
These improvements make the middleware system more robust by:
- Ensuring exceptions are properly handled
- Preventing long-running middlewares from blocking requests
- Preventing repeatedly failing middlewares from being executed
- Providing detailed metrics for monitoring and troubleshooting
By following the guidelines in this document, you can develop robust middlewares that contribute to a stable and reliable application.