# Rate Limiting Configuration ## Overview The HSP system implements configurable rate limiting for HTTP polling operations to prevent overwhelming endpoint devices and ensure controlled data collection. **Requirement**: Req-FR-16 (enhanced) **Phase**: 1.1 - Foundation & Quick Wins **Implementation**: RateLimitedHttpPollingAdapter ## Configuration Schema ### JSON Configuration Add the following to your `hsp-config.json`: ```json { "http_polling": { "rate_limiting": { "enabled": true, "requests_per_second": 10.0, "per_endpoint": true } }, "endpoints": [ { "url": "http://device-1.local/diagnostics", "rate_limit_override": 5.0 }, { "url": "http://device-2.local/diagnostics", "rate_limit_override": 20.0 } ] } ``` ### Configuration Parameters | Parameter | Type | Default | Description | Constraint | |-----------|------|---------|-------------|------------| | `enabled` | boolean | `true` | Enable/disable rate limiting | - | | `requests_per_second` | double | `10.0` | Global rate limit | Must be > 0 | | `per_endpoint` | boolean | `true` | Apply rate limit per endpoint or globally | - | | `rate_limit_override` | double | (optional) | Per-endpoint rate limit override | Must be > 0 | ## Implementation Details ### Algorithm The implementation uses **Google Guava's RateLimiter**, which implements a token bucket algorithm: 1. **Token Bucket**: Tokens are added at a constant rate 2. **Request Processing**: Each request consumes one token 3. **Blocking Behavior**: If no tokens available, request blocks until token is available 4. **Smooth Rate**: Distributes requests evenly over time (no bursts) ### Thread Safety - **Thread-Safe**: RateLimiter is thread-safe, allowing concurrent access - **No Locking**: Uses non-blocking algorithms internally - **Fair Distribution**: Requests are served in FIFO order when rate-limited ### Performance Characteristics - **Memory**: O(1) - minimal overhead per instance - **CPU**: O(1) - constant time acquire operation - **Latency**: Average delay = 1 / requests_per_second ## Usage Examples ### Example 1: Global Rate Limiting ```java // Create base HTTP adapter IHttpPollingPort httpAdapter = new HttpPollingAdapter(httpConfig); // Wrap with rate limiting (10 requests per second) IHttpPollingPort rateLimited = new RateLimitedHttpPollingAdapter( httpAdapter, 10.0 // 10 req/s ); // Use the rate-limited adapter CompletableFuture data = rateLimited.pollEndpoint("http://device.local/data"); ``` ### Example 2: Per-Endpoint Rate Limiting ```java // Different rate limits for different endpoints Map adapters = new HashMap<>(); for (EndpointConfig endpoint : config.getEndpoints()) { IHttpPollingPort baseAdapter = new HttpPollingAdapter(endpoint); double rateLimit = endpoint.getRateLimitOverride() .orElse(config.getDefaultRateLimit()); IHttpPollingPort rateLimited = new RateLimitedHttpPollingAdapter( baseAdapter, rateLimit ); adapters.put(endpoint.getUrl(), rateLimited); } ``` ### Example 3: Dynamic Rate Adjustment ```java // For future enhancement - dynamic rate adjustment public class AdaptiveRateLimiter { private RateLimitedHttpPollingAdapter adapter; public void adjustRate(double newRate) { // Would require enhancement to RateLimitedHttpPollingAdapter // to support dynamic rate changes // Currently requires creating new instance } } ``` ## Testing ### Test Coverage The implementation includes comprehensive tests: 1. **Initialization Tests**: Valid and invalid configuration 2. **Rate Limiting Tests**: Within and exceeding limits 3. **Time Window Tests**: Rate limit reset behavior 4. **Concurrency Tests**: Thread safety with concurrent requests 5. **Burst Traffic Tests**: Handling sudden request spikes 6. **Exception Tests**: Error propagation from underlying adapter ### Running Tests ```bash # Run unit tests mvn test -Dtest=RateLimitedHttpPollingAdapterTest # Generate coverage report mvn test jacoco:report # Verify coverage thresholds (95% line, 90% branch) mvn verify ``` ## Monitoring ### Metrics to Monitor 1. **Rate Limit Wait Time**: Time spent waiting for rate limiter permits 2. **Request Throughput**: Actual requests per second achieved 3. **Queue Depth**: Number of requests waiting for permits 4. **Rate Limit Violations**: Attempts that were throttled ### Example Monitoring Integration ```java public class MonitoredRateLimitedAdapter implements IHttpPollingPort { private final RateLimitedHttpPollingAdapter delegate; private final MetricsCollector metrics; @Override public CompletableFuture pollEndpoint(String url) { long startTime = System.nanoTime(); CompletableFuture result = delegate.pollEndpoint(url); result.thenRun(() -> { long duration = System.nanoTime() - startTime; metrics.recordRateLimitDelay(url, duration); }); return result; } } ``` ## Troubleshooting ### Issue: Requests Too Slow **Symptom**: Data collection takes longer than expected **Solution**: 1. Check rate limit setting: `requests_per_second` 2. Increase rate limit if endpoints can handle it 3. Monitor endpoint response times 4. Consider per-endpoint rate limits ### Issue: Endpoints Overwhelmed **Symptom**: HTTP 429 (Too Many Requests) or timeouts **Solution**: 1. Decrease `requests_per_second` 2. Implement exponential backoff (Phase 1, Task 3.2) 3. Add per-endpoint rate limit overrides 4. Monitor endpoint health ### Issue: Uneven Distribution **Symptom**: Some endpoints polled more frequently than others **Solution**: 1. Enable `per_endpoint: true` in configuration 2. Set appropriate `rate_limit_override` per endpoint 3. Review polling schedule distribution ## Future Enhancements ### Planned Enhancements (Post-Phase 1) 1. **Dynamic Rate Adjustment**: Adjust rate based on endpoint health 2. **Adaptive Rate Limiting**: Auto-tune based on response times 3. **Token Bucket Size**: Configure burst allowance 4. **Rate Limit Warm-up**: Gradual ramp-up after restart 5. **Priority-Based Limiting**: Different rates for different data priorities ### Integration Points - **Backpressure Controller** (Phase 1.2): Adjust rate based on buffer usage - **Health Check** (Phase 3.6): Include rate limit statistics - **Configuration Reload** (Future): Hot-reload rate limit changes ## References ### Requirements Traceability - **Req-FR-16**: Rate limiting for HTTP requests (enhanced) - **Req-Arch-6**: Thread-safe concurrent operations - **Req-NFR-2**: Performance under load ### Related Documentation - [PROJECT_IMPLEMENTATION_PLAN.md](../PROJECT_IMPLEMENTATION_PLAN.md) - Phase 1.1 - [system-architecture.md](../architecture/system-architecture.md) - Adapter pattern - [test-strategy.md](../testing/test-strategy.md) - TDD approach ### External References - [Google Guava RateLimiter](https://github.com/google/guava/wiki/RateLimiterExplained) - [Token Bucket Algorithm](https://en.wikipedia.org/wiki/Token_bucket) --- **Document Version**: 1.0 **Last Updated**: 2025-11-20 **Author**: HSP Development Team **Status**: Implemented (Phase 1.1)