AL+

Limba: RO (română) EN (English)

Scrieți-ne: paul@alplustech.com

Rails CurrentAttributes are nevoie să elimine și starea incidentală

Rails a schimbat curățarea CurrentAttributes în iunie 2025. Separați atributele declarate de starea incidentală și atribuiți separat răspunderea pentru cache.

Read this article in English

Starea locală unei cereri are nevoie de un sfârșit bine definit. Dacă un obiect care păstrează utilizatorul curent își șterge atributul declarat pentru utilizator, dar reține o valoare calculată din datele acestuia, curățarea nu a respectat contractul de izolare al aplicației. Schimbarea CurrentAttributes din Rails, din iunie 2025, a tratat această lacună prin abandonarea instanțelor la limitele ciclului de execuție, în loc să se bazeze doar pe resetarea atributelor declarate.

Privind din noiembrie 2026, lecția de proiectare este să păstrați explicită starea cererii și să atribuiți altui obiect răspunderea pentru cache-urile intenționat partajate. Locul convenabil în care găsiți utilizatorul curent nu ar trebui să devină tacit un depozit pentru valori cu durate diferite de viață. Aceste durate influențează corectitudinea chiar dacă fiecare interogare luată separat este validă.

Discuția a urmat implementării

Rezumatul Rails din 6 iunie 2025 a evidențiat variabilele obișnuite de instanță care puteau trece dintr-o cerere în alta. Modificarea fusese integrată la 2 iunie. Articolul săptămânal discuta lucrări deja integrate în main; nu stabilea că toate versiunile Rails lansate le includeau deja.

Diferențele din cod schimbă apelurile de la intrarea și încheierea execuției pentru a folosi clear_all. Operația resetează instanțele existente și golește registrul lor. Un acces ulterior obține o instanță nouă. Afirmația este mai precisă decât ideea că orice apel reset pe un obiect individual îi șterge acum toate variabilele Ruby de instanță.

Pentru o decizie privind aplicația, stabiliți comportamentul versiunii Rails instalate și mecanismul care încadrează efectiv execuția. Execuția personalizată, din afara ciclului obișnuit al cererii, are nevoie de propria verificare. Integrarea istorică dovedește schimbarea; nu înlocuiește verificarea locurilor în care aplicația livrată creează și încheie contextul de execuție.

Două cereri arată greșeala de responsabilitate

Luați un scenariu propus pentru verificarea regresiei, nu un test executat pentru articol. O cerere identifică utilizatorul A și calculează o valoare din contul acestuia. Calculul păstrează rezultatul într-o variabilă obișnuită de instanță a obiectului CurrentAttributes. Ciclul de execuție resetează apoi atributele declarate, iar o altă cerere, pe contextul reutilizat, identifică utilizatorul B.

Dacă obiectul rămâne același și variabila incidentală nu este eliminată, un acces care reutilizează rezultatul calculat poate întoarce valoarea lui A în cererea lui B. Atributul utilizatorului poate fi corect, în timp ce valoarea derivată este greșită. Verificarea exclusivă a utilizatorului curent declarat ar rata, prin urmare, eșecul relevant.

Consecința exactă depinde de ceea ce controlează valoarea păstrată. O preferință de afișare rămasă de la alt utilizator și un cont selectat greșit au gravități diferite. Niciuna nu ar trebui dedusă numai din mecanism. Verificați valorile calculate efectiv de aplicație și acțiunile care le folosesc înainte să descrieți riscul pentru firmă.

Aceasta explică și de ce un test ar trebui să observe rezultatul derivat. Verificarea faptului că atributul utilizatorului curent devine gol confirmă doar o parte a contractului. Afirmația importantă este că a doua cerere primește propriul rezultat, inclusiv după ce prima cerere urmează o cale de eroare.

Declarați deliberat starea cu viață scurtă

Atributele declarate fac vizibilă starea intenționată a cererii și participă la resetarea atributelor oferită de cadru. Acesta este un motiv să le folosiți pentru valori al căror ciclu de viață corespunde contextului curent. Nu înseamnă că orice informație comodă din aplicație aparține unei clase Current accesibile global.

Un set mic și explicit este mai ușor de înțeles. Dacă o metodă primește direct toate valorile necesare, introducerea stării cererii poate adăuga dependențe ascunse fără un beneficiu util. Când CurrentAttributes are un scop clar, exprimați-l în interfață și păstrați concordanța dintre valorile derivate și datele declarate din care provin.

Resetarea unei referințe nici nu distruge un obiect pe care altă parte a aplicației încă îl deține. Dacă un obiect modificabil ajunge într-un serviciu cu viață lungă, golirea registrului CurrentAttributes nu poate anula cealaltă referință. Schimbarea ciclului de viață limitează o cale precisă de păstrare a stării. Nu garantează universal că datele cererii nu pot ajunge în altă parte.

Același raționament se aplică sarcinilor executate ulterior. Decideți ce identitate ar trebui să folosească o sarcină și stabiliți-o în propriul ciclu real de execuție. O sarcină care rulează mai târziu nu își poate deduce în siguranță dreptul de a acționa doar din starea prezentă când a fost programată.

Dați cache-urilor partajate alt loc

Cel mai puternic contraargument este performanța. Reutilizarea unei valori calculate poate evita munca repetată, iar o echipă poate dori intenționat ca datele să supraviețuiască între cereri. Abandonarea fiecărui obiect la sfârșitul cererii ar contrazice acest scop dacă obiectul ar fi destinat partajării.

Acesta este un motiv să separați responsabilitățile. Un cache partajat are nevoie de o cheie explicită, de reguli de invalidare și de presupuneri privind accesul concurent. Dacă valoarea diferă între conturi, acele presupuneri trebuie să păstreze distincția. Ascunderea cache-ului într-un obiect pentru starea cererii face dificil de observat dacă păstrarea este intenționată sau accidentală.

Pentru o valoare necesară doar într-o cerere, recalcularea sau starea declarată explicit pot fi suficiente. Pentru o valoare costisitoare partajată, folosiți o componentă proiectată pentru acea durată de viață. Decizia ar trebui să urmeze sensul și costul valorii, nu o interdicție generală a cache-ului sau o preferință generală pentru memorarea rezultatelor.

Verificați limita reală

O verificare limitată a regresiei ar trebui să execute două identități distincte prin ciclul real al aplicației, pe un context reutilizat. Observați valoarea derivată cu consecințe, apoi repetați cu un eșec în prima operație. Concentrați testul pe riscul păstrării stării, în loc să verificați detalii private ale registrului care se pot schimba.

Pentru mentenanță software, întrebați ce valori aparțin unei cereri, care sunt partajate deliberat și unde are loc curățarea în versiunea livrată. Problema privește durata de viață a stării. Curățarea corectă nu înlocuiește autorizarea, iar o cerere obișnuită reușită nu dovedește că starea incidentală a dispărut înainte să înceapă următoarea.