Blog ·
O bară de progres care refuză să ghicească
Majoritatea estimărilor de timp sunt inventate. Iată regula care decide când panoul nostru are voie să arate una și ce scrie pe ecran atunci când nu are.
De Provibr
Cineva apasă pe instalare. O mașină trebuie clonată, pornită, configurată și verificată, iar undeva la mijlocul acestui proces clientul vrea să știe un singur lucru: cât va dura.
Răspunsul comod este o numărătoare inversă. Alegeți un număr plauzibil, scădeți o secundă la fiecare secundă, iar ecranul pare că știe ceva. Nu știe. O numărătoare inversă este o promisiune despre un moment, iar acel moment nu îl cunoaște nimeni din clădire.
Așa că am scris regula, i-am dat un număr de versiune și am făcut panoul să spună pe față când nu se califică.
Regula, pe scurt
O estimare de timp apare numai atunci când două condiții sunt adevărate deodată. Trebuie să existe cel puțin douăzeci de rulări reușite ale aceluiași fel de lucrare în ultimele treizeci de zile, iar dispersia trebuie să fie strânsă: percentila nouăzeci nu are voie să fie mai mare de două ori și jumătate mediana. Dacă una dintre ele cade, ecranul arată etapa, timpul scurs și o propoziție care spune că nu există nicio estimare.
Cele trei numere trăiesc într-o singură constantă, cu un câmp de versiune alături, iar nimic altceva din baza de cod nu are voie să aibă o părere despre ele.
| Situație | Ce arată ecranul |
|---|---|
| Mai puțin de douăzeci de rulări comparabile în treizeci de zile | „No reliable time estimate yet”, împreună cu câte rulări au fost înregistrate și câte sunt necesare |
| Douăzeci sau mai multe în treizeci de zile, dar dispersia este prea largă | „No reliable time estimate”, și că rulările au fost prea depărtate între ele |
| Ambele condiții îndeplinite | „Comparable tasks took X to Y minutes, based on N runs in the last 30 days” |
Citiți al treilea rând cu atenție. Este un interval și își numește propria dovadă. Nu este o bară care se târăște spre o linie de sosire și nu se transformă niciodată în „au mai rămas 3 minute”.
De ce un interval și nu o numărătoare inversă
O numărătoare inversă adună două greșeli. Ascunde incertitudinea și se reafirmă la fiecare secundă, așa că eroarea capătă un ritm. Toată lumea a văzut o casetă de copiere promițând patru minute, apoi paisprezece, apoi două, și a învățat în vreo treizeci de secunde că numărul nu înseamnă nimic. Odată ce un cititor învață asta, orice alt număr de pe ecran valorează puțin mai puțin. Un interval, enunțat o singură dată și cu numărul de eșantioane atașat, nu poate face asta.
Condiția de dispersie este partea care face munca adevărată. Douăzeci de eșantioane cu o mediană de patru minute și o percentilă nouăzeci de patruzeci de minute nu sunt o cohortă în care se află o predicție; sunt două populații diferite purtând o singură etichetă, iar media lor produce o cifră cu virgulă și fără sens. Două și jumătate este un număr ales, nu unul dedus, iar câmpul de versiune există tocmai pentru ca schimbarea lui mai târziu să fie o decizie vizibilă.
Cohorta este contul dumneavoastră, și asta este deliberat
Modul evident de a ajunge repede la douăzeci de eșantioane este să măsurați pe toată platforma. Noi nu facem asta. Cohorta este felul de lucrare din interiorul unei singure organizații.
Există două motive, iar al doilea este cel care a decis.
Primul este comparabilitatea. Propriul dumneavoastră istoric este cea mai asemănătoare populație care există: același hipervizor, aceeași rețea, aceleași imagini, aceeași stocare.
Al doilea este că numărul de eșantioane se află pe ecran. O propoziție care spune câte rulări comparabile a văzut platforma în treizeci de zile este o afirmație despre propriul nostru volum, tipărită în panoul unui client, și ar fi dată în schimbul unei estimări puțin mai bune. Limitarea interogării la o singură organizație înseamnă că numărul de pe ecranul dumneavoastră este un fapt despre dumneavoastră.
Consecința practică este că un cont tânăr nu vede nicio estimare o bună bucată de timp, iar acesta este comportamentul corect, nu un gol de umplut. A nu arăta nimic este mai bine decât a arăta un număr care nu înseamnă nimic.
Nu există un tabel de eșantioane
Durata unei sarcini reușite este diferența dintre două momente de timp care sunt deja stocate pe sarcina însăși. Nu există un tabel separat de măsurători.
Asta sună ca o economie evidentă și merită spus de ce a fost o decizie. Un al doilea tabel ar păstra același adevăr de două ori, iar cele două ar începe să difere din clipa în care o curățenie de retenție ar atinge unul și nu pe celălalt. Singurul lucru pe care l-ar adăuga cu adevărat sunt eșantioane care supraviețuiesc sarcinilor din care provin, iar asta contează abia atunci când perioada de retenție este mai scurtă decât fereastra de măsurare. Astăzi retenția este de nouăzeci de zile, iar fereastra de treizeci, așa că întrebarea nu se pune.
O notă de subsol care a mușcat deja această bază de cod: interogarea de percentilă întoarce un double, iar numărătoarea întoarce un bigint, pe care driverul îl dă înapoi ca șir de caractere. Amândouă au nevoie de conversie, iar uitarea exact a uneia dintre cele două eșuează în tăcere, nu zgomotos.
Etape, pentru că un procent trebuie să vină de undeva
Fiecare fel de sarcină poartă o listă de etape, în ordine. O instalare merge pe în așteptare, pregătire, pornire, instalare, finalizare. O descărcare de la un URL merge pe în așteptare, trimis către agent, descărcare, verificare, aplicare. Procentul este dedus din poziția în acea listă, cu excepția cazului în care lucrarea de dedesubt raportează un procent real al ei, iar atunci acela câștigă.
Această suprascriere contează mai mult decât pare. O instalare raportează propria cifră de progres și ea este afișată pe pagina proprie a acelui server; dacă sertarul ar calcula un al doilea număr din pozițiile etapelor, un singur ecran ar purta două procente diferite despre aceeași lucrare. Aceasta este o a doua copie a adevărului, cu un nivel mai sus.
Traducerea din fazele de instalare în etape se află într-un singur loc, scrisă ca o înregistrare exhaustivă și nu ca o instrucțiune switch. Paisprezece faze din două scări de instalare diferite se așază pe cinci etape pe care un client le-ar recunoaște. O fază nouă este o eroare de compilare, nu o etapă care cade în tăcere pe prima.
Învechit nu înseamnă eșuat
Există două praguri pentru cât de proaspăt este ultimul raport de progres: două minute și zece minute. Dincolo de primul, ecranul spune că nu a mai existat nicio actualizare de la un anumit moment. Dincolo de al doilea, spune că nu s-a mai raportat nimic de atunci.
Niciunul nu schimbă starea. Lucrarea poate să meargă perfect. Ce s-a oprit este raportarea, iar un cititor merită să afle asta, în loc să privească o bară care nu s-a mișcat și să tragă singur concluzii. A confunda tăcerea cu eșecul este aceeași greșeală ca închiderea unui incident pentru că măsurătorile au încetat să sosească, iar cele două cuvinte merită ținute separat oriunde apar.
Sertarul nu deține nimic
Sertarul de sarcini de fundal din antet stă deasupra a tot ce am descris, iar regula lui de proiectare este scurtă: nu ține nicio stare proprie despre lucrare. Singura bucată de stare locală din acea componentă este dacă panoul este deschis. Nu există nicio buclă de preluare, niciun interval, niciun al doilea socket. Starea inițială vine din aceeași interogare pe care o folosește pagina de detaliu, iar actualizările în direct sosesc pe magazia comună de timp real.
Un test citește arborele sintactic al componentei și eșuează dacă vreo stare locală ajunge vreodată să țină o stare, o etapă sau un procent. Aceasta este o garanție mai puternică decât o revizuire de cod, din același motiv pentru care un comentariu nu este un test.
Un detaliu de acolo este ușor de inversat: grupurile din sertar sunt calculate după ce se aplică peticul în direct, nu înainte. Calculați-le întâi și o sarcină care tocmai a eșuat rămâne așezată în grupul celor în execuție până la următoarea încărcare completă a paginii, arătând în tăcere un indicator de așteptare lângă ceva care este deja roșu.
Trei defecte pe care numai verificarea le-a găsit
Toate trei s-au compilat, au trecut verificarea de tipuri și au trecut testele unitare.
Confirmarea nu era scrisă nicăieri. Codul se referea la o funcție care nu exista, așa că o instalare reușită producea o sarcină a cărei secțiune de rezultat rămânea goală pentru totdeauna.
O fază de instalare nerecunoscută ștergea etapa înregistrată. Cartografierea întoarce corect nimic pentru o fază pe care nu o cunoaște, dar apelantul scria acel nimic în rând, așa că un agent mai vechi care raporta o fază redenumită ar fi șters etapa unei sarcini care mergea perfect. Remediul este o singură cădere înapoi pe etapa care era deja acolo, iar garda a fost dovedită roșie înainte de a fi crezută.
O sarcină încheiată continua să se învârtă. Etapa unei sarcini finalizate este tot ultima etapă la care a ajuns, ceea ce este corect, pentru că altfel nu ați putea vedea unde s-a oprit. Defectul era că se întreba „este aceasta etapa curentă” comparând nume, când întrebarea adevărată este dacă sarcina mai este activă. O sarcină eșuată nu primește nici ea o bifă verde pe etapa în care a murit: acea etapă a fost abandonată, nu finalizată, așa că are o stare a ei proprie în loc să fie clasată la finalizat sau la neînceput, două lucruri care ar pretinde amândouă ceva neadevărat.
Ce am scrie noi
- Puneți regula de estimare într-o singură constantă cu versiune. La întrebarea „a fost apărabilă estimarea pe care ați arătat-o în martie” se poate răspunde numai dacă știți ce regulă era în vigoare.
- Faceți din absența unei estimări o propoziție, nu un spațiu gol. Un loc gol acolo unde ar trebui să fie un număr se citește ca o defecțiune; „No reliable time estimate yet. 6 of 20 comparable runs recorded.” se citește ca un sistem care știe ce nu știe.
- Limitați cohorta la client și acceptați că un cont nou nu vede nimic o vreme. Alternativa tipărește propriul dumneavoastră volum pe ecranul lui.
- Nu lăsați niciodată un sertar, o insignă sau un widget să țină propria copie a unei stări. Două numere despre o singură lucrare pe un singur ecran sunt mai rele decât niciun număr.
- Separați tăcerea de eșec în vocabular, în modelul de date și pe ecran, și țineți-le separate peste tot.
Limitele sincere: acest strat rulează astăzi pentru patru feluri de lucrare, iar lista este scurtă în mod deliberat, pentru că un fel pe care nimeni nu îl poate porni este o categorie care se afișează goală. Fluxul de anulare poate înregistra o cerere, dar niciun strat de execuție nu confirmă încă una, iar sertarul nu are niciun punct de intrare sub 768 de pixeli lățime de ecran.
Același argument, aplicat lucrului de care se atârnă de obicei o bară de progres, se află în de ce un 200 de la Proxmox nu este un rezultat, iar motivul pentru care am încetat să ne mai încredem în propriile termene se află în un timeout nu este un buton de oprire.
Din munca la platformă de la Provibr.