Trage clients en verloren verbindingen
Kom terug na een onderbreking
De server overleeft nu een trage kijker en laat een dode vallen. Deze les kijkt naar de andere kant van de verbinding: het programma van de kijker, nadat zijn verbinding weg is. Misschien is hij door
De voor de hand liggende manier is het meteen opnieuw proberen, en nog eens als dat mislukt, zo snel als het programma kan. Dat is schadelijk. Als een server herstart, verliezen al zijn kijkers op hetzelfde moment hun verbinding, en als ze het allemaal meteen opnieuw proberen, komt de server terug in een vloedgolf van
Verdubbel het wachten, tot een plafond, met jitter
Het gebruikelijke antwoord heeft drie delen. Wacht vóór elke nieuwe poging, en verdubbel het wachten na elke mislukking: een halve seconde, dan één, dan twee. Stop met verdubbelen bij een plafond, zodat een lange storing een client niet een uur laat wachten als de server allang terug is. En wacht niet precies zo lang: kies een willekeurige tijd tussen nul en de bovengrens, wat jitter heet. Twee clients die de server op hetzelfde moment kwijtraakten, kiezen dan verschillende tijden en spreiden zich. RFC 6455 raadt dit zelf aan, in sectie 7.2.3: na een abnormale sluiting SHOULD een client zijn eerste poging een willekeurige tijd uitstellen en daarna terugschakelen, waarbij hij de vertraging verdubbelt tot een grens.
Het programma hieronder berekent het schema van één client. Een echte client haalt zijn jitter uit een bron van willekeur; hier staat een vaste
Het drukt zes regels af, van attempt 1: wait up to 0.5 s, this time 0.31 s tot attempt 6: wait up to 8.0 s, this time 2.64 s. De bovengrens verdubbelt van 0,5 tot 8,0 en blijft daarna op het plafond. De wachttijden springen daaronder heen en weer: poging 4 wacht 1,6 s, hoewel haar bovengrens 4,0 is. In een echte client zou elke wachttijd een sleep zijn, gevolgd door een nieuwe connect; een geslaagde verbinding zet de pogingteller terug op 1.
Alleen de rekensom voor poging 5. Wat drukt dit af?
print(0.5 * 2 ** 4, round(8.0 * 0.97, 2))
Opnieuw synchroniseren heeft geen geschiedenis nodig
Zodra de kijker weer verbonden is, heeft hij elke score gemist die gebeurde terwijl hij weg was. Hij hoeft er niet om te vragen. Het eerste bericht van de server aan elke kijker is de snapshot bij binnenkomst, het hele bord, dus één bericht brengt een terugkerende kijker bij.
De kijker heeft er één regel bij nodig: onthoud de versie van de laatste snapshot die hij toonde, en negeer elke snapshot waarvan de versie niet nieuwer is. Een snapshot met dezelfde versie zou alleen hetzelfde bord opnieuw tonen, en een oudere zou de scores achteruit laten gaan, wat kan gebeuren als een client even twee verbindingen heeft of een laat bericht leest van de verbinding die hij aan het verlaten was. Het programma hieronder past de regel toe op vier snapshots die aankomen nadat de kijker versie 4 toonde:
Het drukt version 3: ignored, version 5: shown, version 5: ignored en version 6: shown af.
Een client toonde als laatste versie 9 en ontvangt na het opnieuw verbinden een snapshot met versie 9. Wat doet hij?
Waar dit thuishoort
De regel over verouderde snapshots hoort bij het contract van het scorebord, en de client van het eindproject past hem toe. Een volledige connect en zijn bron van willekeur, is iets om te herkennen en niet iets wat deze cursus bouwt: als je de drie delen kent, kun je er een lezen in de documentatie van elke clientbibliotheek en controleren dat hij verdubbelt, een plafond heeft en jitter toevoegt.
Waarom voeg je jitter toe aan de backoff?
Les 6 bewijst scorebord v2 met eigen tests en draait het met een vertraagde kijker en een dode.