Skip to content

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

  1. Rate limiting centralise : token bucket adaptatif par OPCO, partage entre toutes les instances
  2. Gestion des slots : limite le nombre d'appels simultanes (maxSlots)
  3. Priority queue : priorise POST > GET dossier > GET batch/sync
  4. Broadcast rateConfig : informe les instances du budget alloue pour le fallback local
  5. Tracking des instances : suivi des connexions, cleanup a la deconnexion
  6. Generation JWT : token de preuve pour chaque grant

Protocole WebSocket

Messages entrants (instance → hub)

TypeChampsDescription
acquireid, opcoId, method, route, reasonDemande un slot pour appeler l'OPCO
reportid, status, durationMsSignale le resultat de l'appel

Messages sortants (hub → instance)

TypeChampsDescription
grantid, token, validForSlot accorde, JWT inclus
queuedid, positionRequete en attente (pas assez de tokens ou de slots)
errorid, messageErreur (opcoId inconnu, etc.)
rateConfigopcoId, refillRate, maxTokens, maxRefillRate, maxMaxTokensMise 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) : 30s

La duree moyenne est calculee en Exponential Moving Average :

avg = avg_precedent * 0.9 + duration_observee * 0.1

Instance 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) :

  1. Supprimee de Instances pour tous les OPCOs
  2. Toutes ses requetes en queue sont retirees
  3. Tous ses slots actifs sont liberes
  4. Un nouveau rateConfig est broadcast (budget redistribue entre N-1 instances)

JWT

Chaque grant inclut un JWT signe HS256 :

json
{
  "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}) :

RouteMethodeDescription
/admin/instancesGETListe des instances connectees
/admin/keysGETListe des API keys (masquees)
/admin/keysPOSTCreer une API key { name, tenantId }
/admin/keys/:keyDELETERevoquer une API key
/admin/reloadPOSTRecharger la config OPCOs + API keys

Les API keys sont stockees dans un fichier YAML (api-keys.yaml) et gerees par le KeyStore.

Configuration

yaml
# opcos.yaml
opcos:
  opco-ep:
    maxPerMin: 60
    maxSlots: 5
  atlas:
    maxPerMin: 30
    maxSlots: 3

Variables d'environnement :

VariableDefaultDescription
HUB_PORT4000Port du serveur
HUB_JWT_SECRETdev-jwt-secretSecret HMAC pour les JWT
HUB_ADMIN_KEY-Cle admin (vide = admin desactive)
HUB_OPCOS_CONFIGopcos.yamlChemin config OPCOs
HUB_KEYS_CONFIGapi-keys.yamlChemin API keys

Endpoints publics

RouteDescription
/ws?apiKey=...WebSocket (instances Opcovia)
/healthHealth check { status: "ok" }
/metricsMetriques par OPCO (tokens, slots, queue, avgDuration)