Blog ·
Una barra di avanzamento che non indovina
Quasi tutte le stime di tempo sono inventate. Ecco la regola che decide quando il nostro pannello può mostrarne una e che cosa scrive quando non può.
Di Provibr
Qualcuno fa clic su installa. Una macchina va clonata, avviata, configurata e verificata, e da qualche parte nel mezzo il cliente vuole sapere una cosa sola: quanto tempo ci vorrà.
La risposta facile è un conto alla rovescia. Si sceglie un numero plausibile, si toglie un secondo ogni secondo e lo schermo sembra sapere qualcosa. Non sa nulla. Un conto alla rovescia è una promessa su un istante, e in tutta l’azienda nessuno conosce quell’istante.
Perciò abbiamo messo per iscritto la regola, le abbiamo dato un numero di versione e abbiamo fatto in modo che il pannello dica ad alta voce quando non ne ha i requisiti.
La regola, in breve
Una stima di tempo compare solo quando entrambe le condizioni sono vere. Devono esserci almeno venti esecuzioni riuscite dello stesso tipo di lavoro negli ultimi trenta giorni, e la dispersione deve essere stretta: il novantesimo percentile non può superare di due volte e mezza la mediana. Se una delle due manca, lo schermo mostra la tappa, il tempo trascorso e una frase che dice che una stima non c’è.
Quei tre numeri vivono in un’unica costante con accanto un campo di versione, e a nient’altro nel codice è concesso di avere un’opinione su di essi.
| Situazione | Che cosa mostra lo schermo |
|---|---|
| Meno di venti esecuzioni comparabili in trenta giorni | «No reliable time estimate yet», con quante esecuzioni sono state registrate e quante ne servono |
| Venti o più in trenta giorni, ma la dispersione è troppo ampia | «No reliable time estimate», e che le esecuzioni erano troppo distanti fra loro |
| Entrambe le condizioni soddisfatte | «Comparable tasks took X to Y minutes, based on N runs in the last 30 days» |
Legga con attenzione la terza riga. È un intervallo, e nomina le proprie prove. Non è una barra che striscia verso un traguardo, e non diventa mai «3 minutes remaining».
Perché un intervallo e non un conto alla rovescia
Un conto alla rovescia somma due errori. Nasconde l’incertezza e si riafferma ogni secondo, così che l’errore acquista un ritmo. Chiunque ha visto una finestra di copia promettere quattro minuti, poi quattordici, poi due, e ha imparato in una trentina di secondi che quel numero non significa nulla. Una volta imparato questo, ogni altro numero sullo schermo vale un po’ meno. Un intervallo, dichiarato una volta sola con accanto il proprio numero di campioni, non può fare questo.
La condizione sulla dispersione è la parte che fa il lavoro vero. Venti campioni con una mediana di quattro minuti e un novantesimo percentile di quaranta minuti non sono una coorte con dentro una previsione; sono due popolazioni diverse che portano la stessa etichetta, e farne la media produce una cifra con la virgola e senza significato. Due e mezzo è un numero scelto, non ricavato, e il campo di versione esiste perché cambiarlo in seguito sia una decisione visibile.
La coorte è il suo account, ed è una scelta voluta
Il modo ovvio per arrivare in fretta a venti campioni è misurare su tutta la piattaforma. Non lo facciamo. La coorte è il tipo di lavoro all’interno di una singola organizzazione.
Le ragioni sono due, e la seconda è quella che ha deciso.
La prima è la comparabilità. La sua storia è la popolazione più simile che esista: stesso hypervisor, stessa rete, stesse immagini, stesso storage.
La seconda è che il numero di campioni sta sullo schermo. Una frase che dice quante esecuzioni comparabili la piattaforma ha visto in trenta giorni è un’affermazione sul nostro volume di lavoro, stampata nel pannello di un cliente, e verrebbe regalata in cambio di una stima leggermente migliore. Limitare la query a una sola organizzazione significa che il numero sul suo schermo è un fatto che riguarda lei.
La conseguenza pratica è che un account giovane per un po’ non vede alcuna stima, e questo è il comportamento corretto e non una lacuna da riempire. Mostrare niente è meglio che mostrare un numero che non significa nulla.
Non esiste una tabella dei campioni
La durata di un’attività riuscita è la differenza fra due marche temporali già memorizzate sull’attività stessa. Non c’è una tabella separata di misurazioni.
Sembra un risparmio ovvio, e vale la pena dire perché è stata una decisione. Una seconda tabella conterrebbe due volte la stessa verità, e le due divergerebbero la prima volta che una pulizia di conservazione ne tocca una e non l’altra. L’unica cosa che aggiungerebbe davvero sono campioni che sopravvivono alle attività da cui provengono, e questo conta solo quando il periodo di conservazione è più breve della finestra di misurazione. Oggi la conservazione è di novanta giorni e la finestra di trenta, quindi la domanda non si pone.
Una nota che questo codice ha già pagato: la query del percentile restituisce un double e il conteggio restituisce un bigint, che il driver riconsegna come stringa. Servono entrambe le conversioni, e dimenticarne esattamente una fallisce in silenzio anziché ad alta voce.
Tappe, perché una percentuale deve venire da qualche parte
Ogni tipo di attività porta con sé un elenco ordinato di tappe. Un’installazione passa per: in coda, preparazione, avvio, installazione, conclusione. Un download da un URL passa per: in coda, inviato all’agente, scaricamento, verifica, applicazione. La percentuale deriva dalla posizione in quell’elenco, a meno che il lavoro sottostante non riporti una percentuale reale propria, nel qual caso vince quella.
Quella precedenza conta più di quanto sembri. Un’installazione riporta la propria cifra di avanzamento e la cifra viene mostrata nella pagina di quel server; se il cassetto ne calcolasse una seconda dalle posizioni delle tappe, una sola schermata porterebbe due percentuali diverse sullo stesso lavoro. Sarebbe una seconda copia della verità, un livello più in alto.
La traduzione dalle fasi di installazione alle tappe sta in un unico punto, scritta come un record esaustivo e non come uno switch. Quattordici fasi distribuite su due diversi percorsi di installazione si mappano su cinque tappe che un cliente riconoscerebbe. Una fase nuova è un errore di compilazione, non una tappa che scivola in silenzio nella prima dell’elenco.
«Stale» non significa «failed»
Ci sono due soglie sulla freschezza dell’ultimo rapporto di avanzamento: due minuti e dieci minuti. Oltre la prima, lo schermo dice che da un certo orario non arrivano aggiornamenti. Oltre la seconda, dice che da allora non è stato riportato nulla.
Nessuna delle due cambia lo stato. Il lavoro può procedere benissimo. Ciò che si è fermato è la comunicazione, e chi legge merita che glielo si dica, invece di guardare una barra che non si muove e trarre le proprie conclusioni. Confondere il silenzio con il fallimento è lo stesso errore di chiudere un incidente perché le misurazioni hanno smesso di arrivare, e vale la pena tenere le due parole separate ovunque compaiano.
Il cassetto non possiede nulla
Il cassetto delle attività in background nell’intestazione sta sopra tutto questo, e la sua regola di progetto è breve: non conserva alcuno stato proprio sul lavoro. L’unico pezzo di stato locale in quel componente è se il pannello sia aperto. Non c’è un ciclo di richieste, non c’è un intervallo, non c’è un secondo socket. Lo stato iniziale arriva dalla stessa query che usa la pagina di dettaglio, e gli aggiornamenti in tempo reale arrivano dallo store condiviso.
Un test legge l’albero sintattico del componente e fallisce se una qualsiasi variabile di stato locale contiene mai uno stato dell’attività, una tappa o una percentuale. È una garanzia più forte di una revisione del codice, per la stessa ragione per cui un commento non è un test.
Un dettaglio lì dentro è facile da invertire: i gruppi nel cassetto vengono calcolati dopo che la modifica in tempo reale è stata applicata, non prima. Calcolandoli prima, un’attività appena fallita resta nel gruppo di quelle in corso fino al successivo caricamento completo della pagina, e mostra in silenzio un indicatore che gira accanto a qualcosa che è già rosso.
Tre difetti che ha trovato solo la verifica
Tutti e tre compilavano, superavano il controllo dei tipi e passavano i test unitari.
La ricevuta non veniva scritta da nessuna parte. Il codice faceva riferimento a una funzione che non esisteva, quindi un’installazione riuscita produceva un’attività con una sezione di esito che restava vuota per sempre.
Una fase di installazione non riconosciuta azzerava la tappa registrata. La mappatura restituisce correttamente nulla per una fase che non conosce, ma il chiamante scriveva quel nulla nella riga, quindi un agente più vecchio che riportasse una fase rinominata avrebbe cancellato la tappa di un’attività che stava andando benissimo. La correzione è un unico ripiego sulla tappa che c’era già, e la protezione è stata provata rossa prima di darle fiducia.
Un’attività conclusa continuava a girare. La tappa di un’attività completata resta l’ultima che ha raggiunto, il che è corretto, perché altrimenti non si vedrebbe dove è finita. Il difetto era chiedere «questa tappa è quella corrente» confrontando i nomi, quando la domanda vera è se l’attività sia ancora attiva. Anche un’attività fallita non riceve una spunta verde sulla tappa in cui è morta: quella tappa è stata abbandonata e non completata, quindi ha uno stato proprio invece di finire sotto «fatto» o «non iniziato», due voci che affermerebbero entrambe qualcosa di falso.
Che cosa metteremmo per iscritto
- Mettere la regola della stima in un’unica costante con una versione. Alla domanda «la stima che avete mostrato a marzo era difendibile» si può rispondere solo sapendo quale regola era in vigore.
- Fare dell’assenza di una stima una frase e non uno spazio vuoto. Un vuoto dove dovrebbe esserci un numero si legge come un difetto; «No reliable time estimate yet. 6 of 20 comparable runs recorded.» si legge come un sistema che sa che cosa non sa.
- Limitare la coorte al cliente, accettando che i nuovi account per un po’ non vedano nulla. L’alternativa stampa il proprio volume sullo schermo altrui.
- Non lasciare mai che un cassetto, un contrassegno o un widget conservi una copia propria di uno stato. Due numeri su uno stesso lavoro in una stessa schermata sono peggio di nessun numero.
- Separare il silenzio dal fallimento nel vocabolario, nel modello dei dati e sullo schermo, e tenerli separati dappertutto.
I limiti onesti: questo strato oggi funziona per quattro tipi di lavoro, e l’elenco è volutamente corto perché un tipo che nessuno può avviare è una categoria che si mostra vuota. Il flusso di annullamento può registrare una richiesta, ma nessuno strato esecutivo ne conferma ancora una, e il cassetto non ha un punto di accesso sotto i 768 pixel di larghezza dello schermo.
Lo stesso ragionamento, applicato alla cosa a cui di solito è attaccata una barra di avanzamento, sta in perché un 200 di Proxmox non è un esito, e la ragione per cui abbiamo smesso di fidarci delle nostre scadenze sta in un timeout non è un pulsante di arresto.
Dal lavoro di piattaforma di Provibr.