Chapitre 2 Chemin d’envoi : découpage en blocs, concurrence et reprise (clé)

Côté envoi, l’objectif est de s’approcher le plus possible de la « saturation de la bande passante » sur des réseaux fluctuants, tout en limitant au minimum le coût des échecs (ne retransmettre que les blocs défaillants). Ensemble, ces deux objectifs expliquent en grande partie pourquoi les envois paraissent plus rapides.

2.1 Découpage en blocs

  • Le client DOIT découper le fichier en plusieurs blocs ; un bloc est l’unité minimale d’envoi et de nouvelle tentative.
  • Les blocs DEVRAIENT avoir une taille fixe (ou une taille définie selon une politique par fichier) afin de simplifier l’ordonnancement de la concurrence et la représentation de l’état.
  • Bénéfice immédiat : toute défaillance n’affecte qu’un seul bloc, et non le fichier entier.

2.2 Envoi en parallèle

L’objectif de la concurrence n’est pas d’avoir « plus de threads », mais d’éviter trois limites pratiques d’une connexion unique sur des réseaux réels :

  • Démarrage lent et croissance de la fenêtre : une connexion unique monte en débit lentement, surtout avec un RTT interrégional élevé.
  • Gigue du lien : la gigue sur une connexion peut faire chuter la vitesse globale ; la concurrence en atténue l’effet.
  • Bridage par flux : certains réseaux brident un flux unique ; plusieurs flux permettent de se rapprocher du plafond de bande passante (dans le respect des contraintes de conformité).
  • Le client DEVRAIT utiliser une concurrence limitée (par exemple 4 à 12) et la réduire sur les appareils moins puissants pour éviter les pics de mémoire.
  • Le client PEUT adapter la concurrence : l’augmenter lorsque le débit augmente et la diminuer lorsque le taux d’erreur augmente.

2.3 Idempotence et nouvelles tentatives

  • Les envois répétés d’un même bloc DOIVENT être idempotents : les soumissions en double ne doivent pas corrompre un état déjà terminé.
  • Le serveur DEVRAIT garantir l’unicité avec (transferId, fileId, chunkIndex) ou une contrainte équivalente.
  • Le client DOIT mettre en œuvre des nouvelles tentatives avec un délai exponentiel (exponential backoff) ; en cas d’échec, il DEVRAIT ne réessayer que les blocs défaillants.

2.4 Envoi avec reprise

  • Le serveur DOIT pouvoir répondre à la question « quels blocs ont déjà été envoyés », afin que le client puisse ignorer ceux qui sont terminés.
  • L’ensemble des blocs envoyés DEVRAIT être représenté sous forme de bitmap ou d’ensemble de plages, pour éviter que la taille de l’état ne croisse linéairement avec le nombre de blocs.
  • Gain de vitesse : après une coupure réseau, un plantage du navigateur ou un changement de réseau, la reprise ne repart pas de 0 %.

2.5 « Partager pendant l’envoi » (facultatif)

  • Le système PEUT générer un identifiant de transfert utilisable et un lien de partage alors que l’envoi est encore en cours, afin d’accélérer les flux de livraison.
  • Si le partage est autorisé avant la fin de l’envoi, ce que voient les destinataires DOIT être explicite : le contenu incomplet n’est pas encore téléchargeable, ou seule la progression est affichée.