Visto
Programação
Google
Gemini 2.5 Pro
VS
OpenAI
GPT-5.2
Implemente um Limitador de Taxa Concorrente com Janela Deslizante e Filas de Prioridade
Desenhe e implemente um limitador de taxa (rate limiter) thread-safe em Python que suporte as seguintes funcionalidades:
1. **Limitação de Taxa com Janela Deslizante**: Em vez de usar janelas de tempo fixas, implemente um algoritmo de janela verdadeiramente deslizante. Cada cliente (identificado por uma chave string) tem permissão para no máximo `max_requests` requisições dentro de qualquer janela móvel de `window_seconds` segundos.
2. **Níveis de Prioridade**: Cada requisição tem um nível de prioridade (inteiro 1-5, onde 1 é a prioridade mais alta). Quando o limite de taxa é atingido para um cliente, requisições de prioridade mais baixa (número maior) devem ser rejeitadas primeiro. Especificamente, se uma nova requisição com prioridade P chegar e a janela estiver cheia, o limitador deve verificar se existe alguma requisição na janela atual com prioridade estritamente menor (número maior) que P. Se existir, a requisição de prioridade mais baixa (com o maior número) tem seu slot "revogado" e a nova requisição de prioridade mais alta é admitida. A requisição revogada deve ser registrada para que possa ser reportada. Se não houver requisição de prioridade mais baixa para revogar, a nova requisição é rejeitada.
3. **Permissão de Rajada (Burst Allowance)**: Cada cliente pode opcionalmente ter uma permissão de rajada `burst` (por padrão 0). Isto permite até `burst` requisições adicionais além de `max_requests` em uma janela, mas somente se pelo menos metade da duração da janela tiver passado desde a primeira requisição do cliente na janela atual.
4. **Segurança em Threads (Thread Safety)**: O limitador de taxa deve ser seguro para uso a partir de múltiplas threads concorrentemente. Demonstre isto com um cenário de teste.
5. **Estatísticas**: O limitador deve rastrear estatísticas por cliente: total de requisições admitidas, total rejeitadas, total revogadas (removidas por requisições de maior prioridade) e utilização atual da janela (como float de 0.0 a 1.0).
Implemente a seguinte interface:
```python
class RateLimiter:
def __init__(self, max_requests: int, window_seconds: float, default_burst: int = 0):
...
def set_client_burst(self, client_id: str, burst: int) -> None:
"""Override burst allowance for a specific client."""
...
def allow(self, client_id: str, priority: int = 3, timestamp: float = None) -> bool:
"""
Check if a request is allowed. If timestamp is None, use current time.
Returns True if the request is admitted, False if rejected.
"""
...
def get_stats(self, client_id: str) -> dict:
"""
Return a dict with keys: 'admitted', 'rejected', 'revoked', 'utilization'
"""
...
def get_revoked_log(self, client_id: str) -> list:
"""
Return a list of (timestamp, priority) tuples for revoked requests
for the given client, in chronological order.
"""
...
```
Forneça uma implementação completa e executável juntamente com um script de demonstração que:
- Cria um limiter com max_requests=5, window_seconds=10.0, default_burst=2
- Simula uma sequência de requisições de dois clientes com prioridades e timestamps variados que exercitem todas as funcionalidades (expiração da janela deslizante, revogação por prioridade, ativação da rajada e rejeição)
- Imprime as estatísticas e logs de revogação para cada cliente ao final
- Inclui um breve teste multithreaded com pelo menos 4 threads fazendo requisições concorrentes
Certifique-se de tratar casos de borda tais como:
- Validação do valor de prioridade (deve ser 1-5)
- Requisições chegando exatamente nas fronteiras da janela
- Múltiplas revogações em sequência
- Ativação da permissão de rajada precisamente no marco de metade da janela
- IDs de cliente vazios ou desconhecidos em consultas de estatísticas