Writing/Arhitectură
Varianta ieftină a picat la măsurători
Un endpoint pe care îl puteai interoga părea că e de ajuns. Șaptezeci și opt de minute de măsurat pe două conturi reale au arătat că se înșală cu până la patruzeci și trei de minute, iar asta a decis arhitectura.
Voiam o notificare când un prieten intră online într-un joc. Există un endpoint documentat care întoarce când a fost un cont ultima dată online, iar interogarea lui din minut în minut e varianta evidentă: fără socket, fără proces care rulează permanent, o funcție programată și câteva rânduri de cod. Aproape că am construit-o așa.
În loc de asta am petrecut șaptezeci și opt de minute măsurând endpointul pe două conturi reale, iar fiecare cifră a ieșit greșită în alt fel.
Ce au arătat măsurătorile
Câmpul se mișcă după activitate și neregulat, nu continuu. A avansat o dată și pe urmă deloc timp de cincizeci și patru de minute, interval în care contul juca, demonstrabil. Două conturi aflate în aceeași stare, în aceeași clipă, s-au citit la cincisprezece minute distanță, unul învechit, celălalt proaspăt de șaptesprezece secunde. Exact în momentul în care răspunsul conta cel mai mult, câmpul era în urmă cu patruzeci și trei de minute.
Pe lângă asta, nu a lipsit niciodată pentru un cont online, așa că scurtătura tentantă, aceea de a trata o valoare absentă ca prezență, e pur și simplu falsă. Iar interogarea GraphQL pe care o folosesc bibliotecile mai vechi pentru asta a fost scoasă de tot, ceea ce merită știut înainte să construiești pe baza unui tutorial.
“Fiecare variantă ieftină de aici a fost eliminată prin măsurare, nu din preferință. E singurul fel în care am încredere în răspuns.”
Așa că interogarea periodică nu poate răspunde la niciuna dintre cele două întrebări pe care le aveam de fapt: e omul ăsta online acum și tocmai a intrat. Nu e o problemă de reglaj și n-o rezolvă niciun interval de interogare. Ori e socket, ori nu e nimic, ceea ce înseamnă un proces care stă conectat, ceea ce înseamnă un loc în care să ruleze. Varianta scumpă era singura corectă, iar știu asta doar pentru că am măsurat în loc să raționez.
Fiecare protecție e o cicatrice
Conexiunea și-a produs apoi propriile probleme, iar disciplina utilă a fost să scriu pentru ce există fiecare protecție. Sunt șase și niciuna nu e ipotetică.
Serviciul retrimite prezența tuturor celor deja online în momentul în care te conectezi, așa că fără o mică perioadă de grație la pornire, fiecare repornire reanunță jumătate din prieteni în mijlocul sesiunii. Prezența se schimbă continuu, pe măsură ce cineva trece dintr-un meniu în altul, așa că notificările trebuie deduplicate pe sesiune, nu pe eveniment. Serverul de sus oscilează: am măsurat treceri offline-online de 1,2 și 2,1 secunde, care se citesc ca o sosire nouă dacă nu le filtrezi. Iar perioada de așteptare care oprește repetările trebuie să fie persistentă, pentru că una ținută în memorie se șterge la repornire și lasă să treacă exact oscilația pentru care exista.
Bătaia de inimă care mințea
Cea mai urâtă defecțiune nu a fost un crash. Biblioteca nu se reconectează de încredere, iar o dată procesul a stat viu, conectat și complet orb timp de zece ore, raportându-se sănătos tot intervalul. Altă dată a făcut la fel timp de opt.
Se raporta sănătos pentru că bătaia de inimă scria necondiționat că e conectat și pentru că verificarea de conexiune a bibliotecii întreabă doar dacă socketul e deschis. Un socket pe jumătate închis e deschis. Deci monitorizarea nu detecta defecțiunea, ci fabrica aparența de sănătate.
Soluția evidentă e să ceri serverului bătăi de inimă, ca tăcerea să devină un fapt de protocol, nu o deducție. Am încercat. Serverul refuză configurația din start: negocierea nu se termină niciodată, înregistrarea eșuează, iar serviciul intră în buclă de crash. O măsurătoare de referință a confirmat zero cadre primite pe două ferestre de timp, așa că setarea bibliotecii nu e o scăpare, e singurul lucru pe care serverul îl acceptă.
Așa că verificarea de viață se face din afară: procesul iese la deconectare în loc să încerce să se vindece, iar bătaia de inimă susține că e sănătos doar când poate dovedi. Două lecții care merită duse oriunde. O verificare de sănătate care nu poate eșua e mai rea decât niciuna, pentru că transformă o defecțiune într-o tăcere pe care n-o investighează nimeni. Iar când soluția elegantă e refuzată de ceva ce nu controlezi, răspunsul e să măsori ce acceptă și să proiectezi pentru asta, nu să insiști cu cea elegantă.
