La livraison

La règle

FIFO à épuisement. La validation est immédiate, sur la pile de l'émetteur. Le publish le plus externe vide la file avant de rendre la main : vu de l'extérieur, tout est synchrone. Un publish émis depuis un handleMessage est mis en file et livré après le message courant, jamais imbriqué.

Pourquoi

Ordre déterministe, pile bornée, et des tests qui peuvent asserter juste après publish. Un abonné qui lève une exception est signalé mais ne prive ni les abonnés suivants ni les messages suivants.

Dans le chat

gestion_connexion publie acces_reponse puis presence_changee depuis son handleMessage. Les deux sont mis en file, et livrés dans cet ordre une fois la livraison de acces_demande achevée. gestion_messages reçoit donc acces_reponse après coup, et sert l'historique.

Contre-exemple : un cycle

// A publie x dans son handleMessage de y ; B publie y dans son handleMessage de x
handleMessage(message) { if (message.y) this.broker.publish(this, { x: {} }); }
ERROR (broker): delivery budget exhausted (1000 messages in one drain) — probable publish cycle, queue dropped (next: x -> y -> x -> y -> x ...)

Un cycle A→B→A est un diagnostic, pas un gel.

Chronogramme

pile d'appels file du broker bouton.publish({ click }) broker.validate → file.push(click) → drain() pile.handleMessage({ click }) pile.publish({ plates_count }) validate → file.push → drain() : déjà en cours, retour compteur.handleMessage({ plates_count }) la livraison de plates_count commence quand celle de click est terminée : jamais imbriquée [ click ] [ ] ← click en cours de livraison [ plates_count ] ← mis en file [ ] ← livré à son tour
Le drain le plus externe vide la file ; un publish intérieur ne fait qu'ajouter.

Les autres garanties