Blog ·
Ein Fortschrittsbalken, der nicht rät
Die meisten Zeitschätzungen sind erfunden. Hier steht die Regel, wann unser Panel eine zeigen darf, und was auf dem Bildschirm steht, wenn nicht.
Von Provibr
Jemand klickt auf Installieren. Eine Maschine muss geklont, gestartet, konfiguriert und geprüft werden, und mitten darin will der Kunde genau eines wissen: wie lange das dauert.
Die einfache Antwort ist ein Countdown. Man nimmt eine plausible Zahl, zieht jede Sekunde eine Sekunde ab, und der Bildschirm sieht aus, als wüsste er etwas. Er weiß nichts. Ein Countdown ist ein Versprechen über einen Zeitpunkt, und niemand im Haus kennt diesen Zeitpunkt.
Also haben wir die Regel aufgeschrieben, ihr eine Versionsnummer gegeben und das Panel laut sagen lassen, wenn es sie nicht erfüllt.
Die Regel in Kürze
Eine Zeitschätzung erscheint nur, wenn zwei Bedingungen zugleich erfüllt sind. Es muss mindestens zwanzig erfolgreiche Läufe derselben Art von Arbeit in den letzten dreißig Tagen geben, und die Streuung muss eng sein: Das neunzigste Perzentil darf nicht mehr als das Zweieinhalbfache des Medians betragen. Fällt eine der beiden Bedingungen aus, zeigt der Bildschirm die Etappe, die verstrichene Zeit und einen Satz, der sagt, dass es keine Schätzung gibt.
Diese drei Zahlen stehen in einer einzigen Konstante mit einem Versionsfeld daneben, und nichts sonst im Code darf dazu eine Meinung haben.
| Situation | Was der Bildschirm zeigt |
|---|---|
| Weniger als zwanzig vergleichbare Läufe in dreißig Tagen | „No reliable time estimate yet“, dazu wie viele Läufe erfasst sind und wie viele nötig wären |
| Zwanzig oder mehr in dreißig Tagen, aber die Streuung ist zu breit | „No reliable time estimate“, und dass die Läufe zu weit auseinanderlagen |
| Beide Bedingungen erfüllt | „Comparable tasks took X to Y minutes, based on N runs in the last 30 days“ |
Lesen Sie die dritte Zeile genau. Sie ist eine Spanne, und sie nennt ihren eigenen Beleg. Sie ist kein Balken, der auf eine Ziellinie zukriecht, und sie wird nie zu „noch 3 Minuten“.
Warum eine Spanne und kein Countdown
Ein Countdown häuft zwei Fehler aufeinander. Er verbirgt die Unsicherheit, und er behauptet sich jede Sekunde neu, sodass das Falsche einen Rhythmus bekommt. Jeder hat schon einen Kopierdialog gesehen, der vier Minuten verspricht, dann vierzehn, dann zwei, und hat in etwa dreißig Sekunden gelernt, dass die Zahl nichts bedeutet. Hat ein Leser das einmal gelernt, ist jede andere Zahl auf dem Bildschirm ein wenig weniger wert. Eine Spanne, einmal genannt und mit ihrer Stichprobenzahl versehen, kann das nicht.
Die Bedingung an die Streuung ist der Teil, der die eigentliche Arbeit leistet. Zwanzig Stichproben mit einem Median von vier Minuten und einem neunzigsten Perzentil von vierzig Minuten sind keine Kohorte, in der eine Vorhersage steckt; sie sind zwei verschiedene Grundgesamtheiten unter einem Etikett, und sie zu mitteln ergibt eine Zahl mit Nachkommastelle und ohne Bedeutung. Zweieinhalb ist eine gewählte Zahl und keine hergeleitete, und das Versionsfeld gibt es, damit eine spätere Änderung eine sichtbare Entscheidung ist.
Die Kohorte ist Ihr eigenes Konto, und das mit Absicht
Der naheliegende Weg, schnell zwanzig Stichproben zu erreichen, ist eine Messung über die gesamte Plattform. Das tun wir nicht. Die Kohorte ist die Art von Arbeit innerhalb einer einzigen Organisation.
Dafür gibt es zwei Gründe, und der zweite hat entschieden.
Der erste ist die Vergleichbarkeit. Ihre eigene Historie ist die ähnlichste Grundgesamtheit, die es gibt: derselbe Hypervisor, dasselbe Netz, dieselben Images, derselbe Speicher.
Der zweite ist, dass die Stichprobenzahl auf dem Bildschirm steht. Ein Satz, der nennt, wie viele vergleichbare Läufe die Plattform in dreißig Tagen gesehen hat, ist eine Aussage über unser eigenes Volumen, gedruckt im Panel eines Kunden, und sie würde im Tausch gegen eine leicht bessere Schätzung herausgegeben. Die Abfrage auf eine Organisation zu begrenzen bedeutet, dass die Zahl auf Ihrem Bildschirm eine Tatsache über Sie ist.
Die praktische Folge ist, dass ein junges Konto eine Zeit lang gar keine Schätzung sieht, und das ist das richtige Verhalten und keine Lücke, die zu füllen wäre. Nichts anzuzeigen ist besser, als eine Zahl anzuzeigen, die nichts bedeutet.
Es gibt keine Messwerttabelle
Die Dauer einer erfolgreichen Aufgabe ist die Differenz zwischen zwei Zeitstempeln, die ohnehin an der Aufgabe selbst gespeichert sind. Es gibt keine getrennte Tabelle mit Messungen.
Das klingt nach einer offensichtlichen Ersparnis, und es lohnt sich zu sagen, warum es eine Entscheidung war. Eine zweite Tabelle hielte dieselbe Wahrheit zweimal, und die beiden liefen auseinander, sobald ein Aufräumlauf die eine berührt und die andere nicht. Das Einzige, was sie wirklich hinzufügen würde, sind Stichproben, die ihre Aufgaben überleben, und das zählt erst, wenn die Aufbewahrungsfrist kürzer ist als das Messfenster. Heute beträgt die Aufbewahrung neunzig Tage und das Fenster dreißig, also stellt sich die Frage nicht.
Eine Fußnote, die diesen Code schon einmal gebissen hat: Die Perzentilabfrage liefert einen Double, die Zählung einen Bigint, den der Treiber als Zeichenkette zurückgibt. Beide brauchen eine Umwandlung, und genau eine der beiden zu vergessen scheitert leise statt laut.
Etappen, weil ein Prozentsatz irgendwoher kommen muss
Jede Art von Aufgabe trägt eine geordnete Liste von Etappen. Eine Installation durchläuft Warteschlange, Vorbereitung, Start, Installation, Abschluss. Ein Download von einer URL durchläuft Warteschlange, Versand an den Agenten, Download, Prüfung, Anwendung. Der Prozentsatz wird aus der Position in dieser Liste abgeleitet, es sei denn, die zugrunde liegende Arbeit meldet einen eigenen echten Prozentsatz, dann gewinnt dieser.
Diese Vorrangregel wiegt schwerer, als sie aussieht. Eine Installation meldet ihre eigene Fortschrittszahl, und die wird auf der eigenen Seite dieses Servers angezeigt; würde die Schublade eine zweite Zahl aus Etappenpositionen berechnen, trüge ein Bildschirm zwei verschiedene Prozentsätze über dieselbe Arbeit. Das ist eine zweite Kopie der Wahrheit, eine Ebene höher.
Die Übersetzung von Installationsphasen in Etappen steht an genau einer Stelle, geschrieben als vollständiger Datensatz statt als Verzweigung. Vierzehn Phasen aus zwei verschiedenen Installationsabläufen bilden auf fünf Etappen ab, die ein Kunde wiedererkennt. Eine neue Phase ist ein Compilerfehler und keine Etappe, die still auf die erste zurückfällt.
Veraltet ist nicht gescheitert
Es gibt zwei Schwellen dafür, wie frisch die letzte Fortschrittsmeldung ist: zwei Minuten und zehn Minuten. Nach der ersten sagt der Bildschirm, dass es seit einem bestimmten Zeitpunkt keine Aktualisierung gab. Nach der zweiten sagt er, dass seitdem nichts mehr gemeldet wurde.
Keine der beiden ändert den Status. Die Arbeit kann einwandfrei laufen. Aufgehört hat die Meldung, und ein Leser hat es verdient, das zu erfahren, statt einen Balken zu beobachten, der sich nicht bewegt, und daraus eigene Schlüsse zu ziehen. Schweigen mit Scheitern zu verwechseln ist derselbe Fehler wie einen Incident zu schließen, weil die Messungen ausbleiben, und es lohnt sich, die beiden Wörter überall auseinanderzuhalten.
Die Schublade besitzt nichts
Die Schublade für Hintergrundaufgaben in der Kopfleiste sitzt über all dem, und ihre Entwurfsregel ist kurz: Sie hält keinen eigenen Zustand über die Arbeit. Der einzige lokale Zustand in dieser Komponente ist, ob die Schublade geöffnet ist. Es gibt keine Abrufschleife, kein Intervall, keinen zweiten Socket. Der Anfangszustand kommt aus derselben Abfrage, die auch die Detailseite benutzt, und Live-Aktualisierungen kommen über den gemeinsamen Echtzeitspeicher.
Ein Test liest den Syntaxbaum der Komponente und schlägt fehl, sobald ein lokaler Zustand jemals einen Status, eine Etappe oder einen Prozentsatz hält. Das ist eine stärkere Zusicherung als ein Code-Review, aus demselben Grund, aus dem ein Kommentar kein Test ist.
Ein Detail darin dreht man leicht um: Die Gruppen in der Schublade werden nach dem Anwenden des Live-Patches berechnet, nicht davor. Berechnet man sie vorher, bleibt eine gerade gescheiterte Aufgabe bis zum nächsten vollständigen Seitenaufbau in der Gruppe der laufenden sitzen und zeigt still einen Spinner neben etwas, das schon rot ist.
Drei Defekte, die nur die Verifikation gefunden hat
Alle drei ließen sich kompilieren, bestanden die Typprüfung und die Unittests.
Die Quittung wurde nirgends geschrieben. Der Code verwies auf eine Funktion, die es nicht gab, sodass eine erfolgreiche Installation eine Aufgabe erzeugte, deren Ergebnisabschnitt für immer leer blieb.
Eine unbekannte Installationsphase löschte die erfasste Etappe. Die Abbildung liefert für eine Phase, die sie nicht kennt, korrekt nichts zurück, aber der Aufrufer schrieb dieses Nichts in die Zeile, sodass ein älterer Agent, der eine umbenannte Phase meldet, die Etappe einer einwandfrei laufenden Aufgabe gelöscht hätte. Die Behebung ist ein einziger Rückfall auf die Etappe, die bereits dastand, und der Wächter wurde erst rot bewiesen und dann geglaubt.
Eine fertige Aufgabe drehte weiter. Die Etappe einer abgeschlossenen Aufgabe ist immer noch die letzte, die sie erreicht hat, und das ist richtig, weil man sonst nicht sehen könnte, wo sie geendet hat. Der Fehler war, die Frage „ist diese Etappe die aktuelle“ über einen Namensvergleich zu stellen, obwohl die eigentliche Frage lautet, ob die Aufgabe noch aktiv ist. Eine gescheiterte Aufgabe bekommt auf der Etappe, in der sie gestorben ist, auch keinen grünen Haken: Diese Etappe wurde abgebrochen und nicht abgeschlossen, also hat sie einen eigenen Zustand, statt unter erledigt oder nicht begonnen abgelegt zu werden, was beides etwas Unwahres behaupten würde.
Was wir aufschreiben würden
- Die Schätzregel in eine versionierte Konstante legen. Die Frage „war die Schätzung, die Sie im März gezeigt haben, vertretbar“ lässt sich nur beantworten, wenn man weiß, welche Regel damals galt.
- Das Fehlen einer Schätzung zu einem Satz machen, nicht zu einer leeren Fläche. Eine Lücke, wo eine Zahl stehen sollte, liest sich wie ein Fehler; „No reliable time estimate yet. 6 of 20 comparable runs recorded.“ liest sich wie ein System, das weiß, was es nicht weiß.
- Die Kohorte auf den Kunden begrenzen und in Kauf nehmen, dass neue Konten eine Weile nichts sehen. Die Alternative druckt Ihr eigenes Volumen auf deren Bildschirm.
- Niemals eine Schublade, ein Abzeichen oder ein Widget eine eigene Kopie eines Status halten lassen. Zwei Zahlen über einen Auftrag auf einem Bildschirm sind schlimmer als keine Zahl.
- Schweigen von Scheitern trennen, im Wortschatz, im Datenmodell und auf dem Bildschirm, und sie überall getrennt halten.
Die ehrlichen Grenzen: Diese Ebene läuft heute für vier Arten von Arbeit, und die Liste ist bewusst kurz, weil eine Art, die niemand starten kann, eine Kategorie ist, die leer rendert. Der Abbruchablauf kann eine Anfrage erfassen, aber noch bestätigt keine ausführende Ebene einen Abbruch, und die Schublade hat unterhalb von 768 Pixeln Bildschirmbreite keinen Einstiegspunkt.
Dasselbe Argument, angewendet auf das, woran ein Fortschrittsbalken üblicherweise hängt, steht in warum eine 200 von Proxmox kein Ergebnis ist, und der Grund, warum wir unseren eigenen Fristen nicht mehr trauen, steht in ein Zeitlimit ist kein Stoppknopf.
Aus der Plattformarbeit bei Provibr.