Aller au contenu
use-cases / daily-digest-fan-out / hero
CRON · EXEC · DIFFUSION PIPE

Un digest planifié qui se diffuse à 200 boîtes mail

Chaque lundi à 9h, une seule entrée cron réveille un seul conteneur. Le script rend le digest une fois et l'écrit vers une URL pipe avec ?n=200. Deux cents boucles curl — une par abonné — tirent les mêmes octets en parallèle et les remettent à SMTP. La diffusion vit dans le substrat, pas dans votre code.

Lire la doc cron
use-cases / daily-digest-fan-out / mechanism

Cron, exec, pipe — trois appels et c'est fini

L'API Hoody Cron dépose une ligne crontab à 5 champs dans une entrée managée. La ligne exécute un script exec qui rend le digest une fois et le pousse vers un chemin pipe avec n=200. Deux cents boucles d'abonnés tirent le même chemin en parallèle — le serveur ne retient rien, et un lecteur lent ne peut pas bloquer les autres.

cron · entries
POST · planifier
# Lundi 09:00 — entrée cron managéePOST /users/root/entries# Corps envoyé à /users/root/entries{schedule: "0 9 * * 1",command: "bash /scripts/digest.sh"}
exec · digest.sh
PUT · sender
# Rendre une fois — markdown → HTMLdigest=$(render-digest.py)# Pousser les octets sur le chemin pipeecho "$digest" | curl -T - https://pipe.hoody.com/api/v1/pipe/digest-monday?n=200# Le pipe bloque jusqu'à ce que 200 récepteurs se connectent, puis stream
pipe · subscribers
GET · receivers
# 200 boucles curl légères, une par abonnéwhile read addr; docurl -s https://pipe.hoody.com/api/v1/pipe/digest-monday?n=200 \| smtp-send "$addr" &done < subscribers.txt# Les 200 streamés en parallèle — la backpressure gère les lents[INFO] Transfer complete.

Le cron n'est pas devenu plus complexe. La diffusion a été déplacée dans le substrat — le pipe ne retient rien, le script rend une fois, et la boucle n'est que du SMTP en bordure. Pas de file d'attente, pas de table de réessais, pas de siège d'outil de campagne.

use-cases / daily-digest-fan-out / powers

Pourquoi la diffusion HTTP bat la diffusion SMTP

Le design naïf boucle 200 envois SMTP en série, prend 11 minutes, et double-livre quand il plante à mi-chemin. La forme pipe vous donne du parallélisme, de l'idempotence et un conteneur plus petit — gratuitement.

PARALLÉLISME

Deux cents récepteurs, un seul rendu

Le digest est construit une seule fois. Deux cents boucles curl tirent les mêmes octets simultanément. Un run de 4 secondes remplace une boucle série de 11 minutes — le pipe applique de la backpressure aux lecteurs lents sans bloquer les autres.

IDEMPOTENCE

Pas de crash en plein vol à nettoyer

Il n'y a pas de table d'état de campagne à consulter. Si le run meurt avant que les 200 ne se connectent, le TTL du pipe évince la moitié inachevée et le prochain tick cron re-rend. Pas de double livraison, pas de batch à moitié envoyé à réconcilier.

ÉCONOMIE

Un conteneur, 23 heures endormi

Le script se réveille une fois par semaine, tourne quatre secondes, et le conteneur retourne en idle. Vous payez les quatre secondes — pas un service de campagne toujours actif, pas une facture SES par destinataire, pas un siège Mailchimp.

use-cases / daily-digest-fan-out / timing

Ce qui change quand le câble fait la diffusion

Mêmes 200 destinataires, même corps de digest. C'est la forme du run qui bouge — de minutes-de-SMTP-série à secondes-de-HTTP-parallèle.

  1. DURÉE DU RUN4,2 s

    Temps mural du tick cron à la dernière livraison. Le pipe stream vers les 200 récepteurs en parallèle ; le goulot devient le SMTP de l'abonné le plus lent, pas la boucle.

  2. NOMBRE DE RENDUS

    Le corps du digest est calculé une seule fois. Le pipe transmet les mêmes octets à chaque récepteur — pas de re-rendu de template par destinataire, pas de facturation par destinataire, pas de cache par destinataire.

  3. RÉCEPTEURS PAR CHEMIN200

    L'API Hoody Pipe plafonne n à 256. Un digest hebdomadaire à 200 reste confortablement sous le plafond — et un lecteur lent applique de la backpressure mais ne bloque pas les autres.

Limites selon l'API Hoody Pipe : nombre de récepteurs 1–256, TTL pipe de 5 minutes en attente de connexions, 1000 transferts actifs au niveau serveur. L'entrée cron elle-même est une ligne dans /users/root/entries avec schedule, command et un expires_at optionnel.

use-cases / daily-digest-fan-out / steps

Comment le run se déroule, lundi à 9h

Quatre moments. Chacun est un seul appel HTTP que vous feriez à la main. Le cron est le réveil ; exec est le moteur de rendu ; le pipe est le câble ; la boucle est la seule chose que l'agent écrit.

    01
    09:00:00

    Tick cron

    L'entrée managée sur /users/root/entries se déclenche. Schedule : 0 9 * * 1. Command : bash /scripts/digest.sh. La crontab elle-même est un seul enregistrement JSON — pas un DAG Airflow, pas un service de workflow.

    02
    09:00:00

    Rendu unique

    Le script exec tire les données de la semaine, rend le markdown, convertit en HTML, et écrit le corps sur stdout. Un rendu, un payload — pas de boucle de mail-merge par destinataire.

    03
    09:00:00

    PUT pipe ?n=200

    Le script pipe stdout dans curl -T - contre pipe/digest-monday?n=200. Le pipe retient l'upload jusqu'à ce que 200 récepteurs se connectent, puis stream le corps à chacun en parallèle.

    04
    09:00:04

    200 SMTPs

    Deux cents boucles font un curl sur le même chemin et remettent le corps au SMTP de leur abonné. Les lents reçoivent de la backpressure. Les rapides finissent en millisecondes. Tout le run est terminé en quelques secondes.

use-cases / daily-digest-fan-out / punchline

Une entrée cron, un conteneur, deux cents destinataires.

la façon dont vous le faisiez avantla façon dont le substrat le fait
AVANT · WORKER SMTP SÉRIEfor sub in 200: smtp.send(render(sub))11 minutes · à moitié livré au crash · facture par destinataire
APRÈS · UN CHEMIN PIPErender | curl -T - pipe/digest?n=2004 secondes · idempotent · une facture de réveil
Lire la spec pipe
use-cases / daily-digest-fan-out / replaces

Ce que cela remplace

Les outils standards vers lesquels vous vous tournez quand vous voulez envoyer le même email à une liste. Chacun vous facture un palier de service pour ce qui est, au final, un rendu et une boucle HTTP de diffusion.

  • campagnes planifiées SendGridTarification par email pour un payload que votre script a déjà produit
  • digests quotidiens MailchimpToute une UI de campagne et un siège d'audience pour un envoi hebdomadaire
  • jobs cron de mail-merge sur mesureUne boucle série, une table de réessais et un postmortem de batch à moitié envoyé
  • AWS SES + Lambda batch planifiéUne file d'attente, un worker, un rôle IAM et une alarme CloudWatch à materner
  • Resend avec appels API en batchDépense API par destinataire pour un corps qui n'a pas changé entre les envois
  • campagnes drip Customer.ioUn moteur de segmentation pour une liste que vous gardez déjà dans un fichier texte
use-cases / daily-digest-fan-out / cta

Lundi à 9h voulait dire un worker qui broyait du SMTP. Maintenant ça veut dire un tick cron, un conteneur, et un pipe qui fait le reste.

Lire le guide cron
use-cases / daily-digest-fan-out / related

Découvrez les autres