
Soixante conteneurs sur un seul serveur
Une machine bare-metal exécute des dizaines à des centaines de conteneurs Hoody. La dédupplication KSM et BTRFS rend le coût marginal quasi nul.
Vous exécutez une migration de huit heures. Cinq personnes veulent un statut sans consommer de slot de récepteur ni interrompre le flux. Ajoutez ?progress à l'URL du pipe. Quiconque l'ouvre obtient un tableau de bord HTML en direct — octets transférés, vitesse actuelle, ETA, transitions d'état. La migration tourne à pleine vitesse, peu importe combien d'yeux regardent.
?progress est une lecture en side-channel. Elle ne réclame jamais de slot de récepteur, ne crée jamais de backpressure, ne touche jamais aux octets. La migration s'exécute à pleine bande passante peu importe combien de personnes regardent.
Elle colle l'URL du pipe avec ?progress dans le navigateur de son téléphone. Le tableau de bord HTML s'affiche instantanément — état : waiting, 0 % — pas d'installation, pas de login, pas de slot de récepteur consommé.
SSE envoie un événement state: streaming. La barre de progression saute à 22 %, les octets montent, MB/s se stabilise à 118. Le tableau de bord se met à jour tous les 250 ms sans recharger la page.
Elle ferme l'onglet. Sa connexion de spectateur tombe. La migration ne le remarque pas — elle ne s'est jamais trouvée dans le chemin des données. L'expéditeur et son seul véritable récepteur continuent.
Elle rouvre l'URL à l'aube. Le tableau de bord affiche un événement done : 7,6 GB transférés, 8h 2m, sans erreurs. L'état côté serveur survit au rafraîchissement — les retardataires voient toujours la dernière ligne.
Elle transfère l'URL au Slack de l'équipe. Trois ingénieurs l'ouvrent et voient le même état done. Pas de thread de statut à fermer, pas de panel Grafana à retirer des favoris. Une URL, cinq témoins, zéro interruptions.
# 1. Sender — eight-hour migration. Same as always.
tar czf - /var/lib/postgres | curl -T - "$PIPE/api/v1/pipe/migration"
# 2. Receiver — the only client that matters for backpressure.
curl "$PIPE/api/v1/pipe/migration" | tar xzf - -C /restore
# 3. Boss opens the URL on her phone. HTML dashboard. No setup.
# => https://pipe.hoody.com/api/v1/pipe/migration?progress
# 4. You want SSE for a Slack bot? Same URL, different Accept.
curl -N -H "Accept: text/event-stream" \
"$PIPE/api/v1/pipe/migration?progress" \
| grep -E '^event: (progress|state|done)'
# event: state \n data: '{'"state":"streaming","receivers":1'}'
# event: progress \n data: '{'"bytes":5046464512,"mbps":118,"etaSec":840'}'
# event: done \n data: '{'"bytes":8160000000,"durationSec":28800'}'Trois types d'événements SSE. state pour les transitions (idle → waiting → streaming → complete), progress tous les 250 ms tant que les octets circulent (bytesTransferred, vitesse, ETA), done une seule fois à la fin avec les statistiques finales. Jusqu'à cinquante spectateurs par chemin, chacun avec une fenêtre de connexion de cinq minutes.
?progress est un side-channel. Boss, collègue, client externe, on-call — ils ouvrent tous la même URL. Aucun d'eux n'affecte le transfert. Tous voient le même état en direct.
La met en favori sur son téléphone. Vérifie deux fois par jour.
Tableau de bord HTML, pas de loginPipe SSE dans un webhook Slack. Bot de statut en une ligne.
text/event-stream, même URLIntégré dans une page de statut publique. Interroge toutes les 30 s.
0 slot de récepteur, état complet en directConnecté à PagerDuty via l'événement done. Ping quand terminé.
event: done, déclenchement one-shotRegarder la migration est sa propre URL. La migration ne le remarque pas.
Chaque équipe a un moyen de répondre à « où en est-on ? ». La plupart de ces moyens coûtent un service à exécuter, un tableau de bord à câbler, ou un canal de chat à surveiller. Un paramètre de requête sur l'URL du pipe ne coûte rien de tout cela.
Envoyez l'URL. Arrêtez d'envoyer des mises à jour.