Hub Go (WebSocket)
Le Hub est un service Go separe qui centralise le rate limiting pour toutes les instances Opcovia. Il coordonne l'acces aux APIs OPCO via WebSocket.
Responsabilites
- Rate limiting centralise : token bucket adaptatif par OPCO, partage entre toutes les instances
- Gestion des slots : limite le nombre d'appels simultanes (maxSlots)
- Priority queue : priorise POST > GET dossier > GET batch/sync
- Broadcast rateConfig : informe les instances du budget alloue pour le fallback local
- Tracking des instances : suivi des connexions, cleanup a la deconnexion
- Generation JWT : token de preuve pour chaque grant
Protocole WebSocket
Messages entrants (instance → hub)
| Type | Champs | Description |
|---|---|---|
acquire | id, opcoId, method, route, reason | Demande un slot pour appeler l'OPCO |
report | id, status, durationMs | Signale le resultat de l'appel |
Messages sortants (hub → instance)
| Type | Champs | Description |
|---|---|---|
grant | id, token, validFor | Slot accorde, JWT inclus |
queued | id, position | Requete en attente (pas assez de tokens ou de slots) |
error | id, message | Erreur (opcoId inconnu, etc.) |
rateConfig | opcoId, refillRate, maxTokens, maxRefillRate, maxMaxTokens | Mise a jour du budget par instance |
Flux principal : acquire → grant → call → report
Acquire avec file d'attente
Quand le budget est epuise, la requete est mise en queue et traitee des que des tokens se liberent :
Coordination multi-instance
Le hub ajuste le budget global et informe toutes les instances connectees :
Etat par OPCO (OpcoState)
Chaque OPCO a un etat independant :
OpcoState {
Config { maxPerMin: 60, maxSlots: 5 }
// Token bucket
Tokens 45.2 // tokens actuels
MaxTokens 60.0 // max (ajuste dynamiquement)
RefillRate 0.85 // tokens/sec (ajuste dynamiquement)
LastRefill time.Now()
// Slots
ActiveSlots map[requestID] → Slot { grantedAt, validFor, timer }
// Queue
Queue PriorityQueue (min-heap par priorite puis FIFO)
// Stats
AvgDuration map[route] → float64 (EMA 0.9/0.1)
// Instances
Instances map[instanceID] → bool
}Calcul de validFor
Le TTL du slot est base sur la duree moyenne observee pour cette route :
validFor = avgDuration[route] * 2
bornes : [5s, 60s]
default (pas d'historique) : 30sLa duree moyenne est calculee en Exponential Moving Average :
avg = avg_precedent * 0.9 + duration_observee * 0.1Instance tracking
Le hub suit les instances connectees par OPCO. Quand une instance fait un acquire pour un OPCO, elle est ajoutee a Instances[opcoId].
Quand une instance se deconnecte (CleanupInstance) :
- Supprimee de
Instancespour tous les OPCOs - Toutes ses requetes en queue sont retirees
- Tous ses slots actifs sont liberes
- Un nouveau
rateConfigest broadcast (budget redistribue entre N-1 instances)
JWT
Chaque grant inclut un JWT signe HS256 :
{
"opcoId": "opco-ep",
"method": "GET",
"route": "/dossiers",
"instanceId": "inst-42",
"iat": 1711728000,
"exp": 1711728030,
"iss": "opcovia-hub"
}Le JWT est optimise : generation zero-alloc via buffer pool et HMAC pool. L'instance envoie ce JWT dans le header Opcovia-Hub-Token lors de l'appel OPCO. Il sert de preuve que l'appel a ete autorise par le hub.
API Admin
Routes protegees par HUB_ADMIN_KEY (header Authorization: Bearer {key}) :
| Route | Methode | Description |
|---|---|---|
/admin/instances | GET | Liste des instances connectees |
/admin/keys | GET | Liste des API keys (masquees) |
/admin/keys | POST | Creer une API key { name, tenantId } |
/admin/keys/:key | DELETE | Revoquer une API key |
/admin/reload | POST | Recharger la config OPCOs + API keys |
Les API keys sont stockees dans un fichier YAML (api-keys.yaml) et gerees par le KeyStore.
Configuration
# opcos.yaml
opcos:
opco-ep:
maxPerMin: 60
maxSlots: 5
atlas:
maxPerMin: 30
maxSlots: 3Variables d'environnement :
| Variable | Default | Description |
|---|---|---|
HUB_PORT | 4000 | Port du serveur |
HUB_JWT_SECRET | dev-jwt-secret | Secret HMAC pour les JWT |
HUB_ADMIN_KEY | - | Cle admin (vide = admin desactive) |
HUB_OPCOS_CONFIG | opcos.yaml | Chemin config OPCOs |
HUB_KEYS_CONFIG | api-keys.yaml | Chemin API keys |
Endpoints publics
| Route | Description |
|---|---|
/ws?apiKey=... | WebSocket (instances Opcovia) |
/health | Health check { status: "ok" } |
/metrics | Metriques par OPCO (tokens, slots, queue, avgDuration) |