Steven
Steven7 min læsning

Hvad en version 2 faktisk kræver: 206 commits af ærlige tilstande

GeekBye v2 var ikke en funktionsrelease. Det var 206 commits rettet mod én enkelt idé: appen bør aldrig lyve om sin egen tilstand. Her er, hvad det koster — inklusive den lockfile-fejl på én linje, der næsten forhindrede os i at sende noget af det.

Pålidelighed
Udvikling
Release
GeekBye-releases
Hvad en version 2 faktisk kræver: 206 commits af ærlige tilstande

De fleste "version 2"-releases er en bunke nye funktioner med et større tal på. GeekBye v2 var det modsatte. Den sendte næsten ingen ny brugervendt funktionalitet. Dens 206 commits var rettet mod én enkelt, uglamourøs idé:

Appen bør aldrig vise dig en tilstand, der ikke er sand.

Det lyder indlysende, indtil man tæller, hvor mange måder en desktop-app stille og roligt lyver på. Den viser et flueben på en upload, der stadig er undervejs. Den siger "forbundet" over en socket, der døde for et minut siden. Den forbliver tavs, mens dit transskript bliver tabt på gulvet. Ingen af disse er nedbrud. De er værre end nedbrud, fordi appen ser fin ud, mens den tager fejl — og du finder først ud af det senere, når den optagelse, du havde brug for, ikke er der.

v2 var releasen, hvor vi gik på jagt efter hver eneste af disse små løgne.

Løgnen, vi hadede mest: uploaden, der "lykkedes"

GeekBye kan sikkerhedskopiere dine optagelser til Google Drive. I v1 blev forbindelsen til Drive behandlet som en baggrundsdetalje — hvis den virkede, fint; hvis den ikke gjorde, var fejlen for det meste usynlig. Appen ville blive ved med at se forbundet ud. Du ville antage, at dine optagelser var i sikkerhed. Nogle gange var de ikke.

v2 genopbyggede dette omkring ærlige forbindelsestilstande. Drive er nu altid i én af nogle få eksplicitte, sandfærdige tilstande — forbundet, genopretter, afbrudt — og appen udsender hver ændring af den tilstand til hele brugerfladen i det øjeblik, den sker. Når forbindelsen er nede, fortæller et globalt genoprettelsesbanner dig det, overalt, klart og tydeligt. Appen foregiver ikke længere, at en upload lykkedes, når den ikke gjorde. Hvis din sikkerhedskopi ikke kan ske lige nu, ved du det lige nu — ikke i næste uge, når du går og leder efter filen.

Nedenunder er dette en lille arkitektur, ikke et slogan: én kilde til sandhed for forbindelsen, en hændelse, der spredes ud til hver del af brugerfladen, når den ændrer sig, og et banner, der læser direkte fra den tilstand. Der findes ingen vej, hvor forbindelsen er nede, og brugerfladen ser oppe ud, fordi de læser fra den samme kendsgerning.

Løgnen om den tabte optagelse

Den anden store ærlighedsrettelse var optagelsesgenoprettelse. Realtidstransskription kræver en levende forbindelse. I v1 kunne lyden under afbruddet ganske enkelt være væk, hvis den forbindelse hakkede midt i en session — et Wi-Fi-udfald, en tunnel, en VPN-genforbindelse. Transskriptet ville have et hul i sig, og intet fortalte dig det.

v2 ændrede kontrakten: lyd bevares lokalt under et forbindelsesafbrud og forenes bagefter. Når forbindelsen falder, holder GeekBye lyden sikker på din maskine; når den kommer tilbage, sendes den bufrede lyd og syes ind i transskriptet det rigtige sted. Et dårligt halvt minuts netværk koster dig ikke længere et halvt minuts møde. Dette er grundlaget, som de senere pålidelighedsreleases byggede direkte på — genforbind-og-buffer-maskineriet i hvorfor din AI-notetager stopper på dårlig Wi-Fi er den samme idé, hærdet.

Løgnen om popup-stormen

Der er en mere subtil uærlighed i, hvordan apps rapporterer problemer: de over-rapporterer dem. Ét ustabilt netværksøjeblik kan affyre den samme fejl fem gange, og pludselig har du en stak identiske røde toasts, der begraver den ene besked, der betyder noget. Det er heller ikke ærligt — det er støj, der foregiver at være information.

Så v2 tilføjede kategori-nøglet toast-drosling og fejldirigering. Fejl grupperes efter, hvad de rent faktisk er, og hver kategori hastighedsbegrænses, så et enkelt underliggende problem producerer én klar besked, ikke et bombardement. Et hastighedsbegrænsningsproblem dirigeres hen til en hastighedsbegrænsningsbesked; et forbindelsesproblem dirigeres hen til en forbindelsesbesked. Appen fortæller dig hvad der er sandt, én gang — den samme disciplin, der senere forhindrede en 429 i at udgive sig for en udlogning i dagen vores app DDoS'ede sig selv.

Tallet 206 er hele pointen

Ærlige tilstande, genoprettelsesbanner, optagelsesgenoprettelse, toast-dirigering — det er fire idéer. Releasen var 206 commits. Hvor blev resten af?

I den uglamourøse lange hale, som "vis aldrig en falsk tilstand" faktisk kræver. Hvert sted, hvor den gamle brugerflade kunne komme ud af sync med virkeligheden, skulle findes og genkobles til at læse fra sandheden i stedet for en forældet kopi. Hver genforbindelsesvej skulle bringes til at opdatere den delte tilstand i stedet for at gætte lokalt. Dusinvis af små pålidelighedsrettelser på tværs af optagelse, transskription og uploads — hver eneste lukkede et specifikt hul, hvor appen kunne se rigtig ud, mens den tog fejl.

Dette er, hvad en ægte "version 2" koster, når målet er tillid i stedet for funktioner. Der er ingen enkelt overskrifts-commit. Der er 206 små, og releasen føles kun som én ting — rolig — fordi alle 206 trækker i samme retning.

Releasen blev næsten ikke sendt

Her er krigshistorien, og det er en god en, fordi den handler om, at vores egen app lyver for os.

Når du skærer en release, stempler et versionsbump-script det nye tal ud på tværs af projektet. På v2.0.0 opdaterede det appens version — men package-lock.json, npm's præcise afhængighedsregnskab, blev efterladt pegende på den gamle version, 1.9.0. Lokalt var alt fint; ingen geninstallerer afhængigheder bare for at bygge. Men CI kører npm ci, og hele npm ci's opgave er at nægte at fortsætte, hvis lockfilen er uenig med manifestet. Det er en stringensfunktion — og den gjorde præcis, hvad den skulle, ved at fejle byggeriet for den største release, vi nogensinde havde skåret.

Så dukkede en anden, mere lumsk op nedenunder. En nyere npm havde beskåret en valgfri transitiv afhængighedencoding-pakken, som node-fetch trækker ind — ud af lockfilen som unødvendig. Bortset fra at vores CI's rene installation havde brug for den, så installationen gik i stykker på en måde, der ikke havde noget med vores kode at gøre, og alt med, at regnskabet var subtilt forkert.

Begge var rettelser på én linje: resynkroniser lockfilen til den rigtige version, genopret den beskårne post. Begge er også perfekte, ydmygende eksempler på præcis det, v2 handlede om — en tilstand, der hævdede at være sand og ikke var det. Lockfilen er ment som det ærlige regnskab over, hvad appen afhænger af. Da den drev væk fra virkeligheden, gjorde byggeriet præcis, hvad vores app nu gør for brugere: det nægtede at foregive, at alt var fint. At sende en pålidelighedsrelease viser sig at være et pålidelighedsproblem hele vejen ned.

Tre ting v2 lærte os

  1. De farlige fejl er de tavse. Et nedbrud annoncerer sig selv. En falsk "forbundet", en fantom-vellykket upload, et transskript med et usynligt hul — de koster dig tillid netop, fordi intet ser forkert ud. Jag de stille løgne.
  2. Ærlighed er en arkitektur, ikke en besked. Man kan ikke skrue "fortæl sandheden" på en brugerflade som et banner. Banneret skal læse fra den samme enkelte kilde til sandhed som alt andet, ellers bliver det endnu en ting, der kan tage fejl. Én kendsgerning, spredt ud — aldrig to kopier, der kan være uenige.
  3. En version 2, der er tallet værd, er for det meste usynlig. Hvis din v2 er en funktionsliste, er det en v1.5 med marketing. En ægte v2 er 206 commits, som ingen kan pege på hver for sig, der lægger op til et produkt, som ganske enkelt holder op med at lyve for dig.

GeekBye v2.0.0 er fundamentet, som hver release siden har bygget på. For hvad det fundament bærer, se hvorfor din AI-notetager stopper på dårlig Wi-Fi, dagen vores app DDoS'ede sig selv (v2.0.1), og livetransskription når firewallen blokerer WebSockets (v2.0.8). For den ro, det hele var i tjeneste for, hvad er nyt i GeekBye v2.