A legdrágább hibák nem hibaüzenettel jönnek. Sikerjelzéssel jönnek. Egy nap alatt a saját rendszerünkön nyolc olyan esetet mértünk meg, ahol valami zöldet mutatott, és a művelet közben nem történt meg. Nem összeomlás, nem riasztás, nem elszálló szolgáltatás. Egy pipa, egy gépi nyugta („ok: true”, vagyis „a kérést átvettem"), egy nulla kilépési kód, és mögötte a semmi. A közös alak mindegyikben ugyanaz: a jel és a kérdés szétválik. A rendszer válaszol, csak nem arra, amit kérdeztünk. És mivel a válasz zöld, senki nem kérdez utána. Ez az írás hat mért esetet mutat meg a sajátjaink közül, és a végén azt a két kérdést, ami mindegyiket kifogta volna. Előre kimondom a határt: ezek a mi számaink, a mi rendszerünkön. Hogy ugyanezek az arányok másnál is így állnak, azt nem tudjuk.
Amikor a rendszer a befogadást nyugtázza
A belső üzenetsorunk minden elküldött üzenetre „{"ok": true}” választ ad. Kézenfekvő azt olvasni belőle, hogy az üzenet megérkezett. A válasz valójában annyit állít, hogy a sor átvette a küldeményt. A címzetthez való eljutásról semmit nem mond.
Amíg minden gyorsan fut, a kettő között nincs látható különbség. Egy zsúfolt napon viszont van.
Aznap egy döntést közlő üzenet 3 óra 30 percet állt a sorban, miközben a küldő oldalán a küldés sikeresnek látszott (16:15:56-kor indult, 19:45:57-kor ért célba). Ugyanabban a sorozatban a másik három üzenet 42, 39 és 36 percet késett.
A teljes napi kép, hogy az egyedi esetek arányát is lássuk. Egyetlen küldő 399 üzenetet adott ki, ebből 383-nál volt kézbesítési időbélyeg. A 383 késleltetése így oszlott meg: egy percen belül 34, egy és tíz perc között 103, tíz és harminc perc között 134, harminc és hatvan perc között 74, egy óránál többet 38 üzenet állt. Átlag 35 perc, maximum 4 óra 36 perc.
A résztvevők között nagy a szórás: nyolc résztvevő átlaga 6-tól 35 percig terjedt.
Alap: egyetlen küldő 399 üzenete egy nap alatt, ebből 383-nál volt kézbesítési időbélyeg. A jelölt két sávban a késleltetés meghaladta a fél órát, miközben a küldő oldalán minden üzenet sikeresnek látszott.
Van egy csavar, ami ezeket a számokat is felső korláttá teszi. Maga a kézbesítési időbélyeg is késhet: egy üzenetnél 22 perc telt el azután, hogy a címzett már szó szerint idézte a tartalmát, mire a bélyeg felkerült.
Amit ebből érdemes átvinni a saját folyamatára: ha egy rendszer visszaigazolja, hogy „megkaptam", tegye fel a kérdést, hogy ez a visszaigazolás melyik szereplőtől jött. Egy iktatószám azt bizonyítja, hogy a levél bekerült a rendszerbe. Arról, hogy a döntéshozó elolvasta, semmit nem árul el.
Miért nem elég a kilépési kódot megnézni?
A szoftveres eszközök egy számmal jelzik, hogy sikerült-e a művelet. A nulla azt jelenti, hogy rendben, minden más hibát jelöl. Ez a kilépési kód (exit code), és az automatizálásaink erre támaszkodnak.
A leggyakoribb letöltő eszközünk alapbeállításban nullát ad akkor is, ha a szolgáltatás elutasította a kérést. A hibaüzenet ott van a válasz szövegében, a kilépési kód viszont sikert mond. Két külön napon, két különböző résztvevőnél sült el ugyanígy.
Erre van bevett javítás: egy kapcsoló, amitől az eszköz a hibás választ hibaként is jelzi. Egész nap ezt tanítottuk egymásnak, joggal.
Aztán valaki megmérte a saját aznapi módszerét, és talált egy hibafajtát, amin ez a kapcsoló sem fog. Ha a szolgáltatás a hibát is sikeres státusszal adja vissza, akkor minden jelzés zöld marad. Egy nem létező azonosítóra a válasz HTTP 200 (a webes „rendben, megkaptam" státusz), a kilépési kód 0, a válasz szerkezete szabályos, és a hiba egyetlen helyen áll: a tartalomban. Két negatív próbán mérve, plusz egy pozitív kontrollon, ahol egy valódi azonosító valódi adatot adott.
Ez az eset egy valódi munkában fordult elő, egy hivatkozás ellenőrzésekor. Nem sült el, és a mérő kiírta, miért nem: végigolvasta a tartalmat. A saját szavaival: „ha csak a kilépési kódra támaszkodtam volna, átment volna."
Amit ebből érdemes átvinni: a visszaigazolás formája és a tartalma két külön dolog. Egy szabályos, aláírt, iktatott dokumentum is szólhat arról, hogy a kérést elutasították. Ugyanez a szerkezet a webes mérésben is előfordul: egy rosszul bekötött mérőkód hónapokig gyűjthet hiányos adatot úgy, hogy a felület közben zöldet mutat.
A sikeres nyugta, ami után semmi nem történt
Egy este az ütemezett feladatok egyikét kellett korábbi időpontra hozni, és egyben átnevezni, hogy a neve tükrözze az új időt. Két hívás ment ki, mindkettőre „{"ok": true}” jött. Az időpont valóban átállt. A név maradt.
A gyökér-ok egyszerű, és utólag nyilvánvaló: annak az ütemezésnek a neve a mappa neve a fájlrendszerben. Nincs olyan mező, amit át lehetne írni, az átnevezés fájlműveletet igényel, és erre a felületnek nincs útja. Ezt viszont sikerként jelentette.
A kár, ami majdnem lett: egy ütemezés, aminek a nevében 05:00 áll, és 04:00-kor fut. Aki másnap a névből tájékozódik, és a név az első, amit lát, rossz időt olvas ki.
A javítás után négy hordozót vetettünk össze: a mappa nevét, a leíró név-sorát, az ütemezés konfigurációját és a felület által listázott nevet. Mind a négy egyezik.
Az ütemezés nevét a fájlrendszer mappaneve adja, tehát átírható mező nincs hozzá. A felület erre a hívásra is ugyanazt a sikeres nyugtát adta, mint az időpont-átállításra.
A próba, ami állapotot mért különbség helyett
Van egy eszközünk, ami azt vizsgálja, hogy a védelmeink tényleg dolgoznak-e. Elront egy sort a kódban, lefuttatja az ellenőrző készletet, és ha a készlet erre elhasal, akkor a védelem bizonyítottan méri azt a sort. Ez a mutációs próba.
A régi változata „érvényes próba, piros" eredményt adott egy olyan módosításra, ami egyetlen kommentet cserélt ki. Kommentet, tehát olyan szöveget, ami a program működésére nincs hatással.
Az ok az, hogy a próba a készlet kilépési kódját nézte, és az már a módosítás előtt is piros volt. A jelzés így a kiinduló állapotot írta le. A beavatkozás hatásáról semmit nem mondott.
A javítás után ugyanaz a komment-csere hibát jelez, a magyarázatával együtt: a módosítás nem hozott újonnan hibázó esetet. És mivel egy ilyen javítás értéke azon áll, hogy a készlet önmagában stabil-e, ezt is megmértük: három egymás utáni futás beavatkozás nélkül, a hibázó esetek halmaza 2/2/2, a halmazok között nulla eltérés, és a teljes, 170 soros kimenet bájtra azonos.
Amit ebből érdemes átvinni: egy ellenőrzés akkor mond valamit egy változtatásról, ha a változtatás előtti és utáni állapotot összeveti. Egy pillanatfelvétel a módosítás után arról tanúskodik, hol állunk, arról nem, hogy mit tett a beavatkozás.
A dokumentum, ami a saját frissességéről tévedett
Az egyik állapot-rekordunk fejlécében szerepel, mikor frissítették utoljára. Ez a fejléc gépi bélyeget kap, tehát nem lehet elfelejteni és nem lehet elírni.
Egy nap három egymásba ágyazott fejléc állt ugyanabban a rekordban, három különböző idővel: 20:58, 20:32 és 11:31.
A legfelső helyes volt. Egy nyolcezer karakteres rekordnál viszont az olvasó tipikusan a közepén kezd, és ott a 11:31-es időt találja hatályosnak.
A gyökér-ok a védelem körüli mozdulatban volt. A gépi fejléc-írás jól működött; a törzsből viszont kézzel csak az első régi fejléc lett kivéve, a többi a szöveg belsejében maradt.
A javítás után a rekordban egyetlen fejléc van, a hossza 8161 karakterről 7649-re csökkent. A takarítás előtt hat tartalmi horgonyt is leellenőriztünk, hogy a törlés ne vigyen el egész szakaszt. Mind a hat a helyén maradt.
Amit ebből érdemes átvinni: ha egy dokumentum a saját érvényességéről nyilatkozik, a nyilatkozat pontosan egy helyen álljon. Két dátum egy szerződésben mindig azt a kérdést szüli, melyik az igazi.
Miért nem a nagyobb gondosság a válasz?
Kézenfekvő lenne itt egy figyelmeztetéssel zárni: legyünk figyelmesebbek, olvassuk el a válaszokat, ne bízzunk a pipákban. Ez a tanács azonban egy ponton elbukik, és a bukást ugyanaznap háromszor megmértük.
Ugyanazon a napon három saját, percek alatt írt ellenőrző eszköz adott magabiztos, hibás számot.
Az első egy számláló volt, ami a keresett minta idézeteit is találatnak vette. Három találatot jelzett egy rekordra, és egyik sem volt igazi találat: mindhárom idézet abból a leletből, ami épp ezt a hibafajtát dokumentálta. Aki a számra hagyatkozik, a saját bizonyítékát törli ki.
A második egy ellenőrzés, ami rossz dolgot mért, mint amit kérdeztünk tőle. A három találata a szövegtörzs forrás-jelölője volt, és arról a kérdésről, amit mérni akartunk, semmit nem mondott.
A harmadik egy határszám, ami valójában egy mozgó sor pillanatfelvétele volt. Két órával később ugyanaz a lekérdezés más értéket adott.
Mind a három eszközt gondos emberek írták, a hiba felismerésére, aznap. A gondosság a mérő tulajdonsága, és a mérő már hibázott. Ezért nem lehet a gondosságra építeni a védelmet. A jelenség nem csak a saját eszközeinkre áll, hasonló vakfoltot írtunk le az AI önellenőrzéséről is.
Van egy részlet, ami ennél a háromnál a legtöbbet mondja, és pontosan kell fogalmazni. Mind a három hibát egy olvasás fogta meg. Kétszer valaki másé, egyszer a szerzőé, aki tíz percen belül maga vette észre. A számok egymást nem cáfolták; valaki elolvasta, mit takar a szám.
Mind a három eszköz ugyanazon a napon készült, éppen a hibák felismerésére. A hibát egyik esetben sem a mérés fogta meg. Mindháromszor egy olvasás.
A közös alak ez: a mintát számoltuk, és nem azt a szerepet, amit a minta betöltött. Egy szó előfordulása még nem állítás. Egy talált sor még nem az a sor, amit keresünk. Egy nulla kilépési kód még nem elvégzett munka.
Mit kérdezz meg, mielőtt egy zöld pipára építesz?
A hat esetből két kérdés vezethető le, és mindkettő megválaszolható néhány másodperc alatt.
Az első: mi az az objektum, amit ez a mérés tényleg megnézett? Az üzenet befogadását vagy a megérkezését. A kérés elfogadását vagy a végrehajtását. A mostani állapotot vagy a beavatkozás hatását. Ha erre nincs egymondatos válasz, a zöld jelzés még nem az a bizonyíték, aminek látszik.
A második: mi lenne a jel, ha a művelet elbukna? Ha erre az a válasz, hogy ugyanez a jel, akkor a mérés nem mér. A hibát is sikeres státusszal visszaadó szolgáltatás pontosan ilyen: a siker és a bukás jelzése megegyezik, tehát a jelzés nem hordoz információt.
És egy harmadik mozdulat, ami a leginkább kifizetődött nálunk: a fontos állításoknál nézzük meg egy másik hordozón is. Az ütemezés nevénél négy hordozó összevetése zárta le a kérdést. Az üzenetsor esetében a címzett saját üzenetei mondták meg, mit kapott meg valójában. Egyik sem hosszú munka, és mindkettő olyan hibát fog meg, amit a jelzés maga elrejt. Ha a saját számaitokat szeretnétek így, több hordozó felől átnézve látni, arról szól az adatvizualizációs munkánk.
Gyakori kérdések
Mit jelent az, hogy egy rendszer sikert jelez egy meg nem történt műveletre?
Azt, hogy a visszaigazolás egy másik kérdésre válaszol, mint amit feltettünk. A belső üzenetsorunk „ok: true” válasza például azt nyugtázza, hogy a sor átvette az üzenetet. A címzetthez való eljutásról nem nyilatkozik, és a kettő között egy zsúfolt napon 3 óra 30 perc is eltelhet.
Hogyan lehet ellenőrizni, hogy egy zöld visszajelzés valódi-e?
Két kérdés elég hozzá. Az első, hogy pontosan melyik objektumot nézte meg a mérés. A második, hogy mi lenne a jel, ha a művelet elbukna. Ha a bukás ugyanazt a jelet adná, akkor a jelzés nem hordoz információt, és a valódi bizonyíték máshol van: a művelet eredményén.
A hibakód mit mér, és mit nem?
A hibakód a szállítást méri, a tartalmat nem. Mértünk olyan esetet, ahol egy nem létező azonosítóra HTTP 200-as („rendben") státusz, nulla kilépési kód és szerkezetileg szabályos válasz jött, és a hiba kizárólag a válasz tartalmában állt. A kilépési kód után ezért mindig kell egy tartalmi ellenőrzés is: benne van-e a válaszban az, amit kértünk.
Elég-e, ha figyelmesebbek vagyunk?
Önmagában nem. Ugyanazon a napon három saját, a hibák felismerésére írt ellenőrző eszközünk adott magabiztos, hibás számot. A gondosság a mérő tulajdonsága, és a mérő maga is hibázhat. Mind a három esetben egy olvasás fogta meg a hibát: valaki megnézte, mit takar a szám.
Ezek az arányok más rendszerekre is igazak?
Ezt nem tudjuk, és nem is állítjuk. Minden szám a saját rendszerünkön, egyetlen nap alatt mért adat. Amit általánosnak tartunk, az a szerkezet: a jel és a kérdés szétválhat, és ilyenkor a zöld szín önmagában nem bizonyíték.