Naar de inhoud

Blog ·

Een voortgangsbalk die weigert te gokken

De meeste tijdsinschattingen zijn verzonnen. Dit is de regel die bepaalt wanneer ons paneel er een mag tonen, en wat het scherm zegt als dat niet mag.

Door Provibr

Iemand klikt op installeren. Er moet een machine gekloond, opgestart, geconfigureerd en gecontroleerd worden, en ergens halverwege dat alles wil de klant één ding weten: hoe lang gaat dit duren.

Het makkelijke antwoord is een aftelklok. Kies een aannemelijk getal, trek er elke seconde een seconde af, en het scherm ziet eruit alsof het iets weet. Dat is niet zo. Een aftelklok is een belofte over een moment, en niemand in het gebouw kent dat moment.

Dus hebben we de regel opgeschreven, er een versienummer bij gezet, en het paneel hardop laten zeggen wanneer het niet aan de voorwaarden voldoet.

De regel, in het kort

Een tijdsinschatting verschijnt alleen als aan twee voorwaarden tegelijk is voldaan. Er moeten in de afgelopen dertig dagen minstens twintig geslaagde uitvoeringen van hetzelfde soort werk zijn, en de spreiding moet krap zijn: het negentigste percentiel mag niet meer dan twee en een half keer de mediaan zijn. Faalt er één van beide, dan toont het scherm de fase, de verstreken tijd en een zin die zegt dat er geen inschatting is.

Die drie getallen staan in één constante met een versieveld ernaast, en niets anders in de codebase mag er een mening over hebben.

SituatieWat het scherm toont
Minder dan twintig vergelijkbare uitvoeringen in dertig dagen"No reliable time estimate yet", met hoeveel uitvoeringen er zijn vastgelegd en hoeveel er nodig zijn
Twintig of meer in dertig dagen, maar de spreiding is te groot"No reliable time estimate", en dat de uitvoeringen te ver uit elkaar lagen
Aan beide voorwaarden voldaan"Comparable tasks took X to Y minutes, based on N runs in the last 30 days"

Lees de derde rij aandachtig. Het is een bereik, en het noemt zijn eigen bewijs. Het is geen balk die naar een eindstreep kruipt, en het wordt nooit "nog 3 minuten".

Waarom een bereik en geen aftelklok

Een aftelklok stapelt twee fouten op elkaar. Hij verbergt de onzekerheid, en hij bevestigt zichzelf elke seconde opnieuw, zodat de onjuistheid een ritme krijgt. Iedereen heeft weleens een kopieerdialoog vier minuten zien beloven, daarna veertien, daarna twee, en heeft in een seconde of dertig geleerd dat het getal niets betekent. Zodra een lezer dat eenmaal weet, is elk ander getal op het scherm een beetje minder waard. Een bereik, één keer genoemd met het aantal metingen erbij, kan dat niet.

De voorwaarde over de spreiding is het deel dat het echte werk doet. Twintig metingen met een mediaan van vier minuten en een negentigste percentiel van veertig minuten vormen geen cohort waar een voorspelling in zit; het zijn twee verschillende populaties onder één etiket, en ze middelen levert een getal op met een decimaal en zonder betekenis. Twee en een half is een gekozen getal en geen afgeleid getal, en het versieveld bestaat zodat het later wijzigen ervan een zichtbare beslissing is.

Het cohort is je eigen account, en dat is met opzet

De voor de hand liggende manier om snel aan twintig metingen te komen is meten over het hele platform. Dat doen we niet. Het cohort is het soort werk binnen één organisatie.

Er zijn twee redenen, en de tweede gaf de doorslag.

De eerste is vergelijkbaarheid. Je eigen geschiedenis is de meest gelijkende populatie die bestaat: dezelfde hypervisor, hetzelfde netwerk, dezelfde images, dezelfde opslag.

De tweede is dat het aantal metingen op het scherm staat. Een zin die noemt hoeveel vergelijkbare uitvoeringen het platform in dertig dagen zag, is een uitspraak over ons eigen volume, afgedrukt in het paneel van een klant, en zou worden weggegeven in ruil voor een iets betere inschatting. De opvraging beperken tot één organisatie betekent dat het getal op je scherm een feit over jou is.

Het praktische gevolg is dat een jong account een tijdlang helemaal geen inschatting ziet, en dat is het juiste gedrag en geen gat dat gevuld moet worden. Niets tonen is beter dan een getal tonen dat niets betekent.

Er is geen tabel met metingen

De duur van een geslaagde taak is het verschil tussen twee tijdstempels die al op de taak zelf staan. Er is geen aparte tabel met metingen.

Dat klinkt als een vanzelfsprekende besparing, en het is de moeite waard om te zeggen waarom het een beslissing was. Een tweede tabel zou dezelfde waarheid twee keer bevatten, en de twee zouden uit elkaar lopen zodra een opruimronde de ene wel en de andere niet raakte. Het enige wat hij werkelijk zou toevoegen zijn metingen die de taken overleven waar ze uit voortkwamen, en dat doet er pas toe zodra de bewaartermijn korter is dan het meetvenster. Vandaag is de bewaartermijn negentig dagen en het venster dertig, dus die vraag speelt niet.

Eén voetnoot die deze codebase al eerder heeft gebeten: de percentielopvraging geeft een double terug en de telling een bigint, die de driver als string teruggeeft. Allebei moeten ze omgezet worden, en precies één van de twee vergeten faalt stil in plaats van luid.

Fasen, want een percentage moet ergens vandaan komen

Elk soort taak draagt een lijst met fasen op volgorde. Een installatie gaat queued, preparing, booting, installing, finishing. Een download vanaf een URL gaat queued, sent to the agent, downloading, verifying, applying. Het percentage wordt afgeleid uit de positie in die lijst, tenzij het onderliggende werk een echt eigen percentage meldt, en dan wint dat.

Die voorrang doet er meer toe dan het lijkt. Een installatie meldt een eigen voortgangsgetal en dat staat op de eigen pagina van die server; als de lade een tweede getal uit fasestanden zou berekenen, zou één scherm twee verschillende percentages over hetzelfde werk dragen. Dat is een tweede kopie van de waarheid, één laag hoger.

De vertaling van installatiefasen naar fasen staat op precies één plek, geschreven als een uitputtend record in plaats van als een switch. Veertien installatiefasen, verdeeld over twee verschillende installatieladders, komen uit op vijf fasen die een klant herkent. Een nieuwe installatiefase is een compilatiefout en geen fase die stilletjes doorvalt naar de eerste.

Verouderd is niet mislukt

Er staan twee drempels op hoe vers de laatste voortgangsmelding is: twee minuten en tien minuten. Voorbij de eerste zegt het scherm dat er sinds een bepaald tijdstip geen bijwerking is geweest. Voorbij de tweede zegt het dat er sindsdien niets meer is gemeld.

Geen van beide verandert de status. Het werk kan prima draaien. Wat gestopt is, is de rapportage, en een lezer heeft er recht op dat te horen in plaats van naar een balk te kijken die niet beweegt en zelf conclusies te trekken. Stilte verwarren met mislukking is dezelfde fout als een incident sluiten omdat de metingen wegblijven, en het is de moeite waard die twee woorden overal uit elkaar te houden.

De lade bezit niets

De lade met achtergrondtaken in de kopbalk staat boven op dit alles, en zijn ontwerpregel is kort: hij houdt geen eigen toestand over het werk bij. Het enige stukje lokale toestand in dat component is of het paneel open is. Er is geen ophaallus, geen interval, geen tweede socket. De begintoestand komt uit dezelfde opvraging die de detailpagina gebruikt, en live-bijwerkingen komen binnen op de gedeelde realtime-opslag.

Een test leest de syntaxboom van het component en faalt als lokale toestand ooit een status, een fase of een percentage bevat. Dat is een sterkere garantie dan een codereview, om dezelfde reden waarom een commentaarregel geen test is.

Eén detail daarin is makkelijk om te draaien: de groepen in de lade worden berekend nadat de live-patch is toegepast, niet ervoor. Bereken ze eerst en een taak die zojuist is mislukt blijft in de groep met lopend werk staan tot de volgende volledige paginalading, terwijl er stilletjes een draaiend icoon staat naast iets dat al rood is.

Drie defecten die alleen de verificatie vond

Alle drie compileerden ze, kwamen ze door de typecheck en slaagden ze voor de unittests.

De bevestiging werd nergens weggeschreven. De code verwees naar een functie die niet bestond, dus een geslaagde installatie leverde een taak op met een resultaatgedeelte dat voor altijd leeg bleef.

Een niet-herkende installatiefase wiste de vastgelegde fase leeg. De vertaaltabel geeft terecht niets terug voor een installatiefase die zij niet kent, maar de aanroeper schreef dat niets in de rij, dus een oudere agent die een hernoemde installatiefase meldde zou de fase hebben gewist van een taak die prima liep. De reparatie is één terugval op de fase die er al stond, en de bewaking is rood bewezen voordat we hem vertrouwden.

Een afgeronde taak bleef draaien. De fase van een afgeronde taak is nog steeds de laatste fase die hij bereikte, en dat klopt, want anders zou je niet kunnen zien waar hij eindigde. De fout zat in de vraag "is deze fase de huidige" door namen te vergelijken, terwijl de echte vraag is of de taak nog actief is. Een mislukte taak krijgt ook geen groen vinkje op de fase waarin hij stierf: die fase is afgebroken en niet afgerond, dus hij heeft een eigen toestand in plaats van te worden ondergebracht bij afgerond of niet begonnen, die allebei iets onwaars zouden beweren.

Wat wij zouden opschrijven

  1. Zet de regel voor de inschatting in één constante met een versie. De vraag "was de inschatting die je in maart toonde verdedigbaar" is alleen te beantwoorden als je weet welke regel toen gold.
  2. Maak van het ontbreken van een inschatting een zin, geen lege plek. Een leegte waar een getal hoort leest als een fout; "No reliable time estimate yet. 6 of 20 comparable runs recorded." leest als een systeem dat weet wat het niet weet.
  3. Beperk het cohort tot de klant, en accepteer dat nieuwe accounts een tijdlang niets zien. Het alternatief drukt je eigen volume op hun scherm af.
  4. Laat een lade, een insigne of een widget nooit een eigen kopie van een status bijhouden. Twee getallen over één taak op één scherm is erger dan geen getal.
  5. Scheid stilte van mislukking in het vocabulaire, in het datamodel en op het scherm, en houd ze overal gescheiden.

De eerlijke grenzen: deze laag draait vandaag voor vier soorten werk, en de lijst is bewust kort omdat een soort die niemand kan starten een categorie is die leeg rendert. De annuleringsflow kan een verzoek vastleggen maar er is nog geen uitvoerende laag die er een bevestigt, en de lade heeft geen ingang onder 768 pixels schermbreedte.

Dezelfde redenering, toegepast op datgene waar een voortgangsbalk meestal aan vastzit, staat in waarom een Proxmox-200 geen uitkomst is, en waarom we onze eigen deadlines niet meer vertrouwen staat in een timeout is geen stopknop.

Uit het platformwerk bij Provibr.

Begin met één host en één agent

Maak een account aan, installeer de agent met één commando en koppel je eerste Proxmox-host. De proefperiode loopt 14 dagen en vraagt geen betaalgegevens.