Ordinea WebSocket trebuie păstrată și la executarea comenzilor
Action Cable are nevoie de ordine la executarea comenzilor fiecărei conexiuni. Modificarea Rails păstrează paralelismul pentru conexiunile independente.
Un flux WebSocket care livrează mesajele în ordine nu păstrează, prin el însuși, ordinea în care firele de execuție ale serverului execută comenzile. Când starea abonărilor depinde de succesiune, serverul trebuie să mențină ordinea pentru fiecare conexiune. Conexiunile diferite pot fi procesate în continuare în paralel.
Această retrospectivă privește săptămâna de 28 octombrie 2026 și folosește informații disponibile până la 8 noiembrie. Buletinul Rails din 30 octombrie prezintă o schimbare privind ordinea comenzilor pe conexiune. Descrie o modificare în codul Rails, nu dovada că o anumită versiune stabilă sau o aplicație în funcțiune o conține deja.
Coada de lucru de după transport
Propunerea de modificare explică problema la distribuirea lucrului către firele de execuție. Mesajele unei conexiuni erau trimise ca lucrări separate, care se puteau executa simultan sau în altă ordine. Relatarea autorului este datată 25 octombrie; pagina consemnează integrarea în ramura main pe 27 octombrie. Datele privesc discuția și integrarea, nu instalarea într-un mediu de producție.
Diferența se poate pierde ușor într-o discuție despre arhitectură. Transportul poate livra comanda A înaintea comenzii B, iar serverul poate termina B mai întâi. După trimiterea independentă a lucrărilor, serverul are nevoie de o regulă suplimentară dacă B presupune că A a modificat starea comună a conexiunii. Fluxul ordonat nu mai răspunde singur la întrebarea despre aplicație.
Pentru o interfață ipotetică de camere, luați cazul renunțării la o abonare urmate imediat de o nouă abonare. Dacă serverul procesează noua abonare cât timp cea veche încă există, starea întâlnită diferă de succesiunea dorită de utilizator. Dacă eliminarea vine după aceea, și starea finală poate fi diferită. Exemplul explică dependența de ordine; nu descrie un experiment AL+.
O conexiune deschisă cu succes spune, așadar, puțin despre încheierea corectă a unei tranziții între abonări. Pentru firmă, simptomul ar putea fi o interfață care pare conectată, dar așteaptă informații. Această posibilitate ar trebui să îndrepte analiza spre tranziția de stare. Transportul fiabil nu exclude problemele de ordine din restul serverului.
Păstrați ordinea la nivelul potrivit
Propunerea descrie executarea succesivă a lucrărilor asociate unui socket, păstrând grupul de fire de execuție. Conexiunile diferite pot fi procesate în continuare în paralel. Ideea utilă pentru arhitectură este această delimitare: ordonați lucrările care împart aceleași presupuneri despre succesiune, fără a pune toți utilizatorii conectați într-o singură coadă globală.
Un mecanism global de blocare ar fi un răspuns implicit nepotrivit la o cerință locală de ordine. Ar lega utilizatori independenți de lucrările celorlalți. Delimitarea la nivelul conexiunii face dependența explicită. Dacă două comenzi aparțin aceleiași succesiuni de tranziții, ordinea lor contează. Lucrul pentru altă conexiune nu aparține automat acelei succesiuni.
Această alegere nu face inofensivă orice operație lentă. Lucrul executat succesiv pe o conexiune poate întârzia lucrările următoare ale acelei conexiuni. Echipa care evaluează proiectarea ar trebui să înțeleagă compromisul. Nu poate promite simultan paralelism fără restricții și ordine strictă pentru aceleași operații. Rezultatul dorit este un comportament previzibil, cu paralelism acolo unde acesta este compatibil cu regulile aplicației.
Diferența ajută și discuția despre capacitate. Numărul conexiunilor și numărul firelor de execuție descriu lucruri diferite. Niciunul nu dovedește singur că ordinea comenzilor este corectă sau că latența este acceptabilă. Deciziile de capacitate cer dovezi proprii; schimbarea istorică oferă un argument de corectitudine, nu o cifră de performanță transferabilă altui serviciu.
Limita unei soluții în client
Cea mai puternică obiecție practică este că aplicațiile client pot evita suprapunerea schimbărilor de abonare. Un client care așteaptă confirmarea poate reduce expunerea. Pentru o aplicație cu un singur client controlat, aceasta poate părea o variantă mai simplă decât schimbarea distribuirii lucrului pe server. Merită luată în calcul când evaluați constrângerile sistemului existent.
Limita privește cine răspunde de garanție. O întârziere aleasă de client nu dovedește că serverul a terminat lucrul anterior. Alți clienți pot face alegeri diferite. Dacă serverul acceptă o succesiune al cărei sens depinde de comenzile anterioare, regula de ordine are un responsabil mai clar când este păstrată la acea limită a serverului.
Comportamentul clientului rămâne relevant. După reconectare, clientul are nevoie de un mecanism rezonabil de recuperare, iar aplicația trebuie să definească ce înseamnă o abonare încheiată. Aceste preocupări completează ordinea de pe server. Nu ar trebui să sugereze că o singură corecție a distribuirii lucrului rezolvă toate problemele vizibile într-o interfață cu actualizare în timp real.
Păstrați garanția în limitele ei
Ordinea execuției pe conexiune nu stabilește livrarea exact o dată, o ordine globală a evenimentelor sau ordinea între noduri. O conexiune nouă după reconectare are, de asemenea, altă delimitare decât socketul inițial. Cerințele aplicației care depășesc aceste limite cer proiectare și dovezi proprii. Extinderea unei garanții locale ar ascunde lucrul rămas.
Pentru planul de mentenanță, separați modificarea din proiectul Rails, versiunea folosită de aplicație și comportamentul verificat efectiv. Integrarea în main dovedește doar primul lucru. O actualizare propusă ar trebui să identifice versiunea care include corecția înainte ca cineva să promită rezolvarea unui simptom concret.
Mentenanța software ar trebui să păstreze aceste delimitări la predare. Descrieți comenzile care depind de succesiune și locul unde este impusă ordinea. Alegerea paralelismului devine atunci clară: păstrați conexiunile independente în paralel și faceți tranzițiile fiecărei conexiuni în ordinea așteptată de aplicație.
Paul