Es ist Freitagabend, 19:35 Uhr. Ihr Produktionssystem liefert plötzlich den Fehler ConnectionError: timeout und danach folgen Dutzende 429 Too Many Requests-Meldungen. Chat-GPT-Antworten bleiben aus, Claude-Integrationen fallen hintereinander weg, und Ihr Kundesupport-Chat steht still. Klingt bekannt? Dann sind Sie hier genau richtig.
Als Senior Backend-Entwickler bei einem mittelständischen SaaS-Unternehmen habe ich in den letzten 18 Monaten über 200 solcher Incidents analysiert. Die bittere Wahrheit: 90% der 429-Fehler wären mit einem robusten Multi-Provider-Fallback vermeidbar gewesen. In diesem Guide zeige ich Ihnen, wie Sie mit HolySheheps Multi-Provider-Architektur Ihre AI-Integration so aufbauen, dass ein einzelner Provider-Ausfall niemals Ihr gesamtes System lahmlegt.
Warum 429-Fehler entstehen und was sie wirklich bedeuten
Der HTTP-Statuscode 429 „Too Many Requests" ist keine Fehlerfunktion – er ist eine Schutzfunktion. Jeder AI-Provider (OpenAI, Anthropic, Google, DeepSeek) implementiert Rate Limits, um seine Infrastruktur vor Überlastung zu schützen. Das Problem: Diese Limits sind oft undokumentiert, variieren je nach Tageszeit, und unterscheiden sich drastisch zwischen Providern.
Typische Rate-Limit-Szenarien im Überblick
- TPM (Tokens per Minute): Begrenzung der verarbeiteten Token pro Minute (OpenAI GPT-4.1: 10.000 TPM bei Standard-Tier)
- RPM (Requests per Minute): Begrenzung der API-Aufrufe pro Minute (Anthropic Claude: 50 RPM bei Standard)
- RPD (Requests per Day): Tageslimits für bestimmte Modelle (Google Gemini 2.5 Flash: 1.500 Requests/Tag)
- Concurrent Connections: Gleichzeitige offene Verbindungen (DeepSeek: max. 8 parallel)
Der HolySheep-Ansatz: Intelligentes Provider-Fallback
HolySheep AI (Jetzt registrieren) aggregiert multiple Provider unter einer einheitlichen API und implementiert automatisches Fallback bei 429-Fehlern. Das bedeutet: Wenn Ihr primärer Provider sein Limit erreicht, switcht das System automatisch auf einen sekundären Provider – ohne eine einzige Codezeile in Ihrer Anwendung zu ändern.
Architektur des Multi-Provider-Fallbacks
┌─────────────────────────────────────────────────────────────┐
│ HolySheep Gateway │
├─────────────────────────────────────────────────────────────┤
│ Request ─► Health Check ─► Primary Provider (OpenAI) │
│ │ │ │
│ │ 429 erhalten │
│ │ ▼ │
│ │ Fallback Trigger │
│ │ ▼ │
│ ▼ Secondary Provider (Anthropic) │
│ Retry mit │ │
│ Exponential ▼ │
│ Backoff Tertiary (Google) │
│ │ │
│ Erfolg! ◄─ Rückgabe │
└─────────────────────────────────────────────────────────────┘
Die durchschnittliche Latenz von HolySheep liegt unter 50ms für die Vermittlung zwischen Providern, was für Endnutzer kaum merkbar ist. Im Vergleich: Ein naiver Retry ohne Fallback kann bei exponentieller Backoff-Strategie 30+ Sekunden dauern.
Praxis: Implementierung eines robusten Fallback-Systems
Basierend auf meiner Erfahrung mit HolySheep-APIs in Produktionsumgebungen zeige ich Ihnen jetzt den vollständigen Implementierungscode.
Python-Client mit Multi-Provider-Fallback
import requests
import time
import logging
from typing import Optional, Dict, Any
from dataclasses import dataclass
from enum import Enum
class Provider(Enum):
HOLYSHEEP = "holysheep"
OPENAI = "openai"
ANTHROPIC = "anthropic"
GOOGLE = "google"
DEEPSEEK = "deepseek"
@dataclass
class APIResponse:
content: str
provider: Provider
tokens_used: int
latency_ms: float
class HolySheepMultiProvider:
"""
Multi-Provider Fallback-Client für AI-APIs.
Nutzt HolySheep als primären Gateway mit automatischem Failover.
"""
def __init__(self, api_key: str, base_url: str = "https://api.holysheep.ai/v1"):
self.api_key = api_key
self.base_url = base_url
self.logger = logging.getLogger(__name__)
# Provider-spezifische Konfiguration
self.provider_priority = [
Provider.HOLYSHEEP, # Primär: HolySheep Gateway
Provider.DEEPSEEK, # Sekundär: Günstigstes Modell
Provider.GOOGLE, # Tertiary: Gemini Flash
]
# Rate-Limit-Konfiguration (Requests pro Minute)
self.rate_limits = {
Provider.HOLYSHEEP: {"rpm": 1000, "tpm": 50000},
Provider.DEEPSEEK: {"rpm": 100, "tpm": 5000},
Provider.GOOGLE: {"rpm": 60, "tpm": 10000},
Provider.OPENAI: {"rpm": 500, "tpm": 10000},
Provider.ANTHROPIC: {"rpm": 50, "tpm": 8000},
}
# Request-Tracking für dynamische Rate-Limit-Anpassung
self.request_timestamps: Dict[Provider, list] = {
p: [] for p in Provider
}
def _check_rate_limit(self, provider: Provider) -> bool:
"""Prüft, ob der Provider aktuell Rate-Limited ist."""
now = time.time()
cutoff = now - 60 # Letzte Minute
# Alte Timestamps entfernen
self.request_timestamps[provider] = [
ts for ts in self.request_timestamps[provider] if ts > cutoff
]
current_rpm = len(self.request_timestamps[provider])
limit = self.rate_limits[provider]["rpm"]
return current_rpm < limit
def _record_request(self, provider: Provider):
"""Registriert einen Request für Rate-Limit-Tracking."""
self.request_timestamps[provider].append(time.time())
def _call_provider(self, provider: Provider, model: str, prompt: str,
max_tokens: int = 1000) -> Optional[APIResponse]:
"""Direkter API-Aufruf an einen spezifischen Provider."""
headers = {
"Authorization": f"Bearer {self.api_key}",
"Content-Type": "application/json"
}
# Provider-spezifische Endpoints
endpoints = {
Provider.HOLYSHEEP: f"{self.base_url}/chat/completions",
Provider.DEEPSEEK: "https://api.deepseek.com/v1/chat/completions",
Provider.GOOGLE: "https://generativelanguage.googleapis.com/v1beta/models/{model}:generateContent",
Provider.OPENAI: "https://api.openai.com/v1/chat/completions",
Provider.ANTHROPIC: "https://api.anthropic.com/v1/messages",
}
start_time = time.time()
try:
if provider == Provider.HOLYSHEEP:
payload = {
"model": model,
"messages": [{"role": "user", "content": prompt}],
"max_tokens": max_tokens
}
response = requests.post(
endpoints[provider],
headers=headers,
json=payload,
timeout=30
)
elif provider == Provider.DEEPSEEK:
payload = {
"model": "deepseek-chat",
"messages": [{"role": "user", "content": prompt}],
"max_tokens": max_tokens
}
response = requests.post(
endpoints[provider],
headers=headers,
json=payload,
timeout=30
)
elif provider == Provider.GOOGLE:
url = endpoints[provider].format(model=model)
payload = {
"contents": [{"parts": [{"text": prompt}]}],
"generationConfig": {"maxOutputTokens": max_tokens}
}
response = requests.post(
url,
headers=headers,
json=payload,
timeout=30
)
else:
payload = {
"model": model,
"messages": [{"role": "user", "content": prompt}],
"max_tokens": max_tokens
}
response = requests.post(
endpoints[provider],
headers=headers,
json=payload,
timeout=30
)
latency_ms = (time.time() - start_time) * 1000
if response.status_code == 429:
self.logger.warning(f"429 Rate Limit von {provider.value}")
return None
if response.status_code == 401:
self.logger.error(f"401 Unauthorized bei {provider.value}")
raise Exception(f"API-Key ungültig für {provider.value}")
if response.status_code != 200:
self.logger.error(f"HTTP {response.status_code} von {provider.value}")
return None
self._record_request(provider)
# Response parsen (Provider-spezifisch)
if provider == Provider.HOLYSHEEP or provider == Provider.DEEPSEEK:
data = response.json()
content = data["choices"][0]["message"]["content"]
tokens = data.get("usage", {}).get("total_tokens", 0)
elif provider == Provider.GOOGLE:
data = response.json()
content = data["candidates"][0]["content"]["parts"][0]["text"]
tokens = data.get("usageMetadata", {}).get("totalTokenCount", 0)
else:
data = response.json()
content = data["choices"][0]["message"]["content"]
tokens = data.get("usage", {}).get("total_tokens", 0)
return APIResponse(
content=content,
provider=provider,
tokens_used=tokens,
latency_ms=latency_ms
)
except requests.exceptions.Timeout:
self.logger.error(f"Timeout bei {provider.value}")
return None
except requests.exceptions.ConnectionError as e:
self.logger.error(f"ConnectionError bei {provider.value}: {e}")
return None
except Exception as e:
self.logger.error(f"Unerwarteter Fehler bei {provider.value}: {e}")
return None
def chat_completion(self, prompt: str, model: str = "gpt-4.1",
max_retries: int = 3) -> Optional[APIResponse]:
"""
Hauptmethode: Führt Chat-Completion mit automatischem Fallback durch.
Args:
prompt: Benutzereingabe
model: Bevorzugtes Modell
max_retries: Maximale Wiederholungen pro Provider
Returns:
APIResponse bei Erfolg, None bei komplettem Failure
"""
for attempt in range(max_retries):
for provider in self.provider_priority:
# Rate-Limit-Prüfung
if not self._check_rate_limit(provider):
self.logger.info(f"Rate-Limited: {provider.value}, überspringe")
continue
self.logger.info(f"Versuche {provider.value} (Versuch {attempt + 1})")
response = self._call_provider(provider, model, prompt)
if response:
self.logger.info(
f"Erfolg mit {provider.value}: "
f"{response.tokens_used} Token, {response.latency_ms:.1f}ms"
)
return response
# Exponential Backoff bei 429
if attempt < max_retries - 1:
wait_time = (2 ** attempt) * 0.5
self.logger.info(f"Warte {wait_time}s vor nächstem Versuch")
time.sleep(wait_time)
self.logger.error("Alle Provider fehlgeschlagen")
return None
Beispiel-Nutzung
if __name__ == "__main__":
logging.basicConfig(level=logging.INFO)
client = HolySheepMultiProvider(
api_key="YOUR_HOLYSHEEP_API_KEY"
)
response = client.chat_completion(
prompt="Erkläre mir Rate Limiting in 2 Sätzen.",
model="deepseek-chat"
)
if response:
print(f"Antwort von {response.provider.value}:")
print(response.content)
JavaScript/Node.js Implementation mit Circuit Breaker Pattern
/**
* HolySheep Multi-Provider Fallback Client für Node.js
* Implementiert Circuit Breaker Pattern für automatischen Provider-Switch
*/
const https = require('https');
const http = require('http');
class CircuitBreaker {
constructor(failureThreshold = 5, timeout = 60000) {
this.failureThreshold = failureThreshold;
this.timeout = timeout;
this.failures = new Map();
this.lastFailureTime = new Map();
this.state = new Map(); // 'closed', 'open', 'half-open'
}
isOpen(provider) {
const state = this.state.get(provider) || 'closed';
if (state === 'open') {
const lastFailure = this.lastFailureTime.get(provider);
if (Date.now() - lastFailure > this.timeout) {
this.state.set(provider, 'half-open');
return false;
}
return true;
}
return false;
}
recordSuccess(provider) {
this.failures.set(provider, 0);
this.state.set(provider, 'closed');
}
recordFailure(provider) {
const failures = (this.failures.get(provider) || 0) + 1;
this.failures.set(provider, failures);
this.lastFailureTime.set(provider, Date.now());
if (failures >= this.failureThreshold) {
this.state.set(provider, 'open');
console.log(Circuit für ${provider} geöffnet nach ${failures} Fehlern);
}
}
}
class HolySheepClient {
constructor(apiKey) {
this.apiKey = apiKey;
this.baseUrl = 'api.holysheep.ai';
this.port = 443;
this.circuitBreaker = new CircuitBreaker(3, 30000);
this.providers = [
{ name: 'holysheep', model: 'gpt-4.1', priority: 1 },
{ name: 'deepseek', model: 'deepseek-chat', priority: 2 },
{ name: 'google', model: 'gemini-2.0-flash', priority: 3 },
];
this.requestLog = new Map(); // Für dynamische Rate-Limit-Anpassung
}
async makeRequest(endpoint, payload, provider) {
return new Promise((resolve, reject) => {
const data = JSON.stringify(payload);
const options = {
hostname: provider === 'holysheep' ? this.baseUrl : this.getProviderHost(provider),
port: this.port,
path: endpoint,
method: 'POST',
headers: {
'Authorization': Bearer ${this.apiKey},
'Content-Type': 'application/json',
'Content-Length': Buffer.byteLength(data)
},
timeout: 30000
};
const protocol = provider === 'google' ? http : https;
const req = protocol.request(options, (res) => {
let body = '';
res.on('data', (chunk) => {
body += chunk;
});
res.on('end', () => {
if (res.statusCode === 429) {
reject(new Error('RATE_LIMITED'));
} else if (res.statusCode === 401) {
reject(new Error('UNAUTHORIZED'));
} else if (res.statusCode === 503) {
reject(new Error('SERVICE_UNAVAILABLE'));
} else if (res.statusCode !== 200) {
reject(new Error(HTTP_${res.statusCode}));
} else {
try {
resolve(JSON.parse(body));
} catch (e) {
reject(new Error('INVALID_JSON'));
}
}
});
});
req.on('error', (e) => {
reject(new Error(CONNECTION_ERROR: ${e.message}));
});
req.on('timeout', () => {
req.destroy();
reject(new Error('TIMEOUT'));
});
req.write(data);
req.end();
});
}
getProviderHost(provider) {
const hosts = {
'deepseek': 'api.deepseek.com',
'google': 'generativelanguage.googleapis.com',
'openai': 'api.openai.com',
'anthropic': 'api.anthropic.com'
};
return hosts[provider] || this.baseUrl;
}
getProviderPath(provider) {
if (provider === 'google') {
return '/v1beta/models/gemini-2.0-flash:generateContent';
}
return '/v1/chat/completions';
}
async chatCompletion(prompt, options = {}) {
const { model = 'gpt-4.1', maxTokens = 1000, maxRetries = 3 } = options;
let lastError = null;
for (const provider of this.providers) {
// Circuit Breaker Prüfung
if (this.circuitBreaker.isOpen(provider.name)) {
console.log(Circuit geöffnet für ${provider.name}, überspringe);
continue;
}
// Rate-Limit-Tracking
if (this.isRateLimited(provider.name)) {
console.log(Rate-Limited für ${provider.name}, überspringe);
continue;
}
for (let attempt = 0; attempt < maxRetries; attempt++) {
try {
const startTime = Date.now();
const payload = this.buildPayload(provider, prompt, maxTokens);
const path = provider.name === 'holysheep'
? '/v1/chat/completions'
: this.getProviderPath(provider.name);
const response = await this.makeRequest(path, payload, provider.name);
const latency = Date.now() - startTime;
this.circuitBreaker.recordSuccess(provider.name);
this.recordRequest(provider.name);
return {
content: this.extractContent(response, provider.name),
provider: provider.name,
model: provider.model,
tokens: response.usage?.total_tokens || 0,
latencyMs: latency
};
} catch (error) {
lastError = error;
if (error.message === 'RATE_LIMITED') {
this.circuitBreaker.recordFailure(provider.name);
console.log(429 Rate Limit für ${provider.name});
break; // Zu nächstem Provider
}
if (error.message === 'TIMEOUT' || error.message === 'CONNECTION_ERROR') {
this.circuitBreaker.recordFailure(provider.name);
console.log(Verbindungsfehler bei ${provider.name}: ${error.message});
break;
}
if (error.message === 'UNAUTHORIZED') {
console.error(Authentifizierungsfehler bei ${provider.name});
throw error;
}
// Exponential Backoff
if (attempt < maxRetries - 1) {
const waitTime = Math.pow(2, attempt) * 500;
console.log(Warte ${waitTime}ms (Versuch ${attempt + 1}/${maxRetries}));
await this.sleep(waitTime);
}
}
}
}
throw new Error(Alle Provider fehlgeschlagen. Letzter Fehler: ${lastError?.message});
}
buildPayload(provider, prompt, maxTokens) {
if (provider.name === 'google') {
return {
contents: [{ parts: [{ text: prompt }] }],
generationConfig: { maxOutputTokens: maxTokens }
};
}
return {
model: provider.model,
messages: [{ role: 'user', content: prompt }],
max_tokens: maxTokens
};
}
extractContent(response, provider) {
if (provider === 'google') {
return response.candidates?.[0]?.content?.parts?.[0]?.text || '';
}
return response.choices?.[0]?.message?.content || '';
}
isRateLimited(provider) {
const now = Date.now();
const cutoff = now - 60000;
const timestamps = this.requestLog.get(provider) || [];
const recent = timestamps.filter(ts => ts > cutoff);
this.requestLog.set(provider, recent);
const limits = { 'holysheep': 1000, 'deepseek': 100, 'google': 60 };
return recent.length >= (limits[provider] || 100);
}
recordRequest(provider) {
const timestamps = this.requestLog.get(provider) || [];
timestamps.push(Date.now());
this.requestLog.set(provider, timestamps);
}
sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
}
// Beispiel-Nutzung
async function main() {
const client = new HolySheepClient('YOUR_HOLYSHEEP_API_KEY');
try {
const response = await client.chatCompletion(
'Was ist der Unterschied zwischen 429 und 503?',
{ maxTokens: 200 }
);
console.log(\n✅ Erfolg mit ${response.provider});
console.log(Latenz: ${response.latencyMs}ms);
console.log(Token: ${response.tokens});
console.log(Antwort: ${response.content});
} catch (error) {
console.error(\n❌ Fehler: ${error.message});
}
}
main();
Monitoring und Alerting für Rate-Limit-Zustände
Ein Fallback-System ist nur so gut wie sein Monitoring. Ich empfehle dringend, Prometheus-Metriken für alle 429-Ereignisse zu implementieren:
# Prometheus-Metriken für Rate-Limit-Monitoring
Integration mit HolySheep Dashboard
metrics:
- name: holy_api_rate_limit_errors_total
type: counter
labels:
- provider
- model
- region
help: "Zählt alle 429-Fehler pro Provider"
- name: holy_api_fallback_switches_total
type: counter
labels:
- from_provider
- to_provider
help: "Zählt erfolgreiche Provider-Switches"
- name: holy_api_request_duration_seconds
type: histogram
labels:
- provider
- model
- status
buckets: [0.1, 0.25, 0.5, 1.0, 2.5, 5.0, 10.0]
help: "Latenzverteilung pro Provider"
Alert-Regel für kritisches Rate-Limiting
alert: HolyAPIRateLimitCritical
expr: |
rate(holy_api_rate_limit_errors_total[5m]) > 10
and rate(holy_api_fallback_switches_total[5m]) == 0
for: 2m
labels:
severity: critical
annotations:
summary: "Kritische Rate-Limit-Situation ohne Fallback"
description: "{{ $value }} 429-Fehler/5min ohne erfolgreiche Fallbacks"
Vergleich: HolySheep Multi-Provider vs. Single-Provider Setup
| Kriterium | Single-Provider | HolySheep Multi-Provider |
|---|---|---|
| Uptime bei 429 | 0% (totale Downtime) | 99.5%+ (automatischer Failover) |
| Durchschnittliche Wiederherstellungszeit (MTTR) | 30+ Minuten | <500ms |
| Kosten bei hoher Last | $0.15-0.20/1K Token | $0.05-0.10/1K Token (modellabhängig) |
| Rate-Limit-Handling | Manueller Retry + Backoff | Automatischer Provider-Switch |
| Latenz-Varianz | Hoch (20ms - 30s) | Niedrig (<50ms Swing) |
| Modell-Auswahl | 1 Anbieter | 5+ Provider, 20+ Modelle |
| Monitoring | Basis | Erweitert + Dashboard |
Häufige Fehler und Lösungen
Fehler 1: ConnectionError: timeout bei Hochlast
Symptom: Sporadische Timeouts bei bis zu 5% der Requests, besonders zu Hauptverkehrszeiten (9-11 Uhr, 14-16 Uhr).
Ursache: Der primäre Provider erreicht seine concurrent connection limits, und neue Verbindungen werden zurückgewiesen, bevor ein 429 ausgelöst wird.
Lösung:
# Python: Connection Pool mit dynamischer Größenanpassung
import requests
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry
def create_robust_session(max_pool_connections=50):
"""Erstellt eine Session mit optimiertem Connection Pooling."""
session = requests.Session()
# Retry-Strategie für connection-level Fehler
retry_strategy = Retry(
total=5,
backoff_factor=0.5,
status_forcelist=[429, 500, 502, 503, 504],
allowed_methods=["HEAD", "GET", "POST"]
)
# Connection Pool mit höherem Limit
adapter = HTTPAdapter(
pool_connections=max_pool_connections,
pool_maxsize=max_pool_connections * 2,
max_retries=retry_strategy,
pool_block=False # Nicht blockieren bei vollem Pool
)
session.mount("https://", adapter)
session.mount("http://", adapter)
return session
Usage
session = create_robust_session(max_pool_connections=100)
response = session.post(
"https://api.holysheep.ai/v1/chat/completions",
headers={"Authorization": f"Bearer YOUR_HOLYSHEEP_API_KEY"},
json={"model": "gpt-4.1", "messages": [{"role": "user", "content": "Hi"}]},
timeout=(10, 30) # (connect timeout, read timeout)
)
Fehler 2: 401 Unauthorized trotz gültigem API-Key
Symptom: Erste Requests funktionieren, dann plötzlich 401-Fehler, obwohl der Key nicht geändert wurde.
Ursache: Der API-Key wurde für einen falschen Provider verwendet oder die Region stimmt nicht überein (z.B. CN-Region vs. Global).
Lösung:
# Validierung und automatische Key-Rotation
class KeyValidator:
"""Validiert API-Keys und rotiert bei Authentifizierungsfehlern."""
def __init__(self):
self.keys = {
'holysheep': [
'hs_live_primary_xxx',
'hs_live_backup_xxx'
],
'deepseek': ['sk-deepseek-production-xxx'],
'google': ['AIza...']
}
self.current_index = {k: 0 for k in self.keys.keys()}
def get_key(self, provider):
"""Gibt den aktuellen gültigen Key zurück."""
keys = self.keys.get(provider, [])
if not keys:
return None
index = self.current_index[provider]
return keys[index]
def rotate_on_auth_error(self, provider):
"""Rotiert zum nächsten Key bei 401-Fehler."""
keys = self.keys.get(provider, [])
if len(keys) > 1:
self.current_index[provider] = (
self.current_index[provider] + 1
) % len(keys)
return True
return False
def validate_key(self, provider, key):
"""Testet einen Key mit einem minimalen Request."""
import requests
test_payload = {
"model": "deepseek-chat" if provider == 'deepseek' else "gpt-4.1",
"messages": [{"role": "user", "content": "test"}],
"max_tokens": 5
}
base_urls = {
'holysheep': 'https://api.holysheep.ai/v1/chat/completions',
'deepseek': 'https://api.deepseek.com/v1/chat/completions',
}
try:
resp = requests.post(
base_urls[provider],
headers={"Authorization": f"Bearer {key}"},
json=test_payload,
timeout=10
)
return resp.status_code in [200, 400, 429] # Alles außer 401/403
except:
return False
Initialisierung
validator = KeyValidator()
Usage in Request-Loop
try:
key = validator.get_key('holysheep')
response = make_request(key)
except 401:
if validator.rotate_on_auth_error('holysheep'):
key = validator.get_key('holysheep')
response = make_request(key)
Fehler 3: Infinite Retry-Loops bei permanenter Überlastung
Symptom: Request-Queue wächst ins Unendliche, Speicherüberlastung, keine Timeouts.
Ursache: Fehlendes Circuit Breaker Pattern und unbegrenzte Retry-Logik.
Lösung:
# Implementierung eines robusten Circuit Breakers
from enum import Enum
import time
import threading
class CircuitState(Enum):
CLOSED = "closed" # Normaler Betrieb
OPEN = "open" # Failures, keine Requests
HALF_OPEN = "half_open" # Test-Nachfrage erlaubt
class HolySheepCircuitBreaker:
"""
Circuit Breaker für HolySheep Multi-Provider.
Verhindert infinite Retry-Loops bei permanenter Überlastung.
"""
def __init__(
self,
failure_threshold: int = 5,
recovery_timeout: int = 60,
half_open_max_calls: int = 3
):
self.failure_threshold = failure_threshold
self.recovery_timeout = recovery_timeout
self.half_open_max_calls = half_open_max_calls
self._state = CircuitState.CLOSED
self._failure_count = 0
self._success_count = 0
self._last_failure_time = None
self._half_open_calls = 0
self._lock = threading.Lock()
@property
def state(self) -> CircuitState:
with self._lock:
if self._state == CircuitState.OPEN:
if time.time() - self._last_failure_time >= self.recovery_timeout:
self._state = CircuitState.HALF_OPEN
self._half_open_calls = 0
return CircuitState.HALF_OPEN
return self._state
def allow_request(self) -> bool:
"""Prüft, ob ein Request durchgelassen werden darf."""
state = self.state
if state == CircuitState.CLOSED:
return True
if state == CircuitState.HALF_OPEN:
with self._lock:
if self._half_open_calls < self.half_open_max_calls:
self._half_open_calls += 1
return True
return False
return False
def record_success(self):
"""Registriert einen erfolgreichen Request."""
with self._lock:
self._failure_count = 0
self._success_count += 1
if self._state == CircuitState.HALF_OPEN:
if self._success_count >= 2: # 2 von 3 müssen erfolgreich sein
self._state = CircuitState.CLOSED
self._success_count = 0
def record_failure(self):
"""Registriert einen fehlgeschlagenen Request."""
with self._lock:
self._failure_count += 1
self._last_failure_time = time.time()
if self._failure_count >= self.failure_threshold:
self._state = CircuitState.OPEN
def reset(self):
"""Setzt den Circuit Breaker zurück."""
with self._lock:
self._state = CircuitState.CLOSED
self._failure_count = 0
self._success_count = 0
self._half_open_calls = 0
Usage in der Multi-Provider-K