- Add DISCOVERY_LOG_LEVEL=debug - Add DISCOVERY_SHOW_PROGRESS=true - Temporary changes for debugging InitializerProcessor fixes on production
5.3 KiB
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_TIMEOUTenvironment variable (default: 5 seconds) - Per middleware class via the
$middlewareTimeoutsparameter in theMiddlewareInvokerconstructor
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
MiddlewarePriorityAttributeto 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:
// 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:
// 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 executeCircuitState::OPEN: Too many failures, middleware is not allowed to executeCircuitState::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.