Săriți la conținut

Blog ·

O pauză care ținea comanda deschisă

O așteptare dintr-un flux ținea cererea de comandă deschisă pe toată durata ei. Remediul a fost un prag și nu o bifă, iar numărul a fost măsurat.

De Provibr

Un flux poate conține o așteptare. Aprovizionați o mașină, dați agentului o clipă, apoi trimiteți comanda următoare. Până săptămâna aceasta, acea așteptare era un somn înăuntrul cererii care pornise fluxul, ceea ce însemna că un client care plasa o comandă stătea uitându-se la o rotiță pe toată durata pauzei.

Vechea limită de sus era de cinci minute. Cineva putea așadar să construiască un flux care arăta cu totul rezonabil și al cărui efect era un formular de comandă de cinci minute.

Acum, când o rulare se poate opri și poate fi continuată de un lucrător, pauza nu mai trebuie să se petreacă înăuntrul cererii. Limita de sus s-a mutat la treizeci de zile. Întrebarea interesantă nu este însă plafonul. Este unde stă linia dintre o pauză pe care cererea o poate absorbi și o pauză care ar trebui să suspende rularea.

Pragul este măsurat, nu ales

Treizeci de secunde.

Întrebarea pe care am pus-o nu a fost „cât de lungă poate fi o pauză”, care nu are răspuns, ci „câtă pauză tolerează deja cererea în care rulează fluxul acesta”, care are. Acea cerere este comanda.

Măsurat față de ce se petrece deja în ea: un nod de acțiune așteaptă în mod implicit șaizeci de secunde o comandă și poate fi configurat până la trei sute, iar o notificare cu e-mail costă cam o jumătate de secundă pentru fiecare destinatar. O pauză care mai adaugă o jumătate de minut peste asta este de apărat. O pauză care adaugă un minut întreg nu este.

Există aici o capcană în care am intrat dinadins, în loc să o ocolim. Alegerea comodă ar fi fost să punem pragul la vechea limită de sus, de trei sute de secunde, fiindcă atunci fiecare graf existent se poartă exact ca înainte și nu se miră nimeni. Este și greșită: păstrează întreaga clasă de problemă care a stârnit schimbarea. Grafurile cu o pauză între treizeci și unu și trei sute de secunde se poartă acum, într-adevăr, altfel. Comanda lor se încheie mai devreme, iar restul fluxului urmează mai târziu. Acesta este câștigul, nu prețul lui.

Plafonul de treizeci de zile este o regulă de produs și nu o limită tehnică. Mecanismul de așteptare ar ține bucuros o rulare timp de un an. Ce nu poate ține un an este o organizație în care nimeni nu își mai amintește de ce o rulare este deschisă.

De ce este un prag și nu o bifă

Alternativa evidentă este un comutator „așteaptă durabil” pe nod. Nu am construit unul, iar motivul este o întrebare la care nu puteți răspunde.

Dacă ar exista o bifă, când ați vrea să fie stinsă? Răspunsul cinstit este niciodată. Așteptarea durabilă este un amănunt de implementare: cel care scrie un flux exprimă „fă o pauză aici atâta timp” și nu are nicio părere despre faptul că asta costă un rând de bază de date. O setare a cărei valoare corectă este mereu aceeași nu este o setare, este un lucru pe care ați uitat să îl hotărâți.

Așa că cel care scrie tastează un număr de secunde, iar pragul hotărăște. Sub linie, parcurgerea pur și simplu doarme, înăuntrul cererii, fără să coste nimic. Deasupra ei, rularea își scrie continuarea în coadă, cu o oră de trezire, iar apelantul se întoarce numaidecât.

Pasul care apare în cele din urmă în jurnalul rulării poartă un indicator de durabilitate și timpul scurs măsurat cu adevărat, nu pe cel cerut, fiindcă acestea nu sunt același număr, iar diferența este singurul fel de a vedea că a rămas coada în urmă.

Fluxuri care cheamă fluxuri, și două limite verificate de câte două ori fiecare

A doua jumătate a muncii acesteia este un nod de subflux: un flux care rulează alt flux și îl așteaptă.

Asta creează două feluri de a construi ceva ce nu se încheie niciodată, iar ele seamănă îndeajuns cât să vă ispitească să le verificați împreună. Nu sunt același lucru. Un ciclu este infinit. Un lanț prea adânc este finit, dar prea lung. Dacă răspundeți la amândouă cu o singură funcție, un ciclu este raportat drept „prea adânc”, iar cel care scrie se apucă să caute un lanț lung, deși al lui are două fluxuri.

Așadar sunt două întrebări, iar fiecare este pusă de două ori.

Sunt puse o dată atunci când un flux este salvat, static, față de celelalte fluxuri din organizație. Verificarea aceea trebuie să existe fiindcă este singurul loc în care un mesaj de eroare bun este cu putință: poate numi fluxul care închide bucla.

Sunt puse din nou în timpul rulării. Verificarea aceea trebuie să existe fiindcă fluxurile sunt editate în mod independent. Fluxul A este salvat și este în regulă. Cineva editează apoi fluxul C, care arată acum înapoi către A. Nimic nu a revalidat A. Verificarea statică este o politețe față de cel care scrie; cea dinamică este garanția adevărată.

Merită numite două amănunte de implementare. Întrebarea „poate fluxul acesta să ajungă la sine în cel puțin un pas” răspunde deopotrivă cazului direct și celui indirect, într-o singură interogare, iar „cel puțin unul” este întreaga definiție: o cale de zero pași ar face ca orice flux să ajungă la sine. Iar parcurgerea de adâncime își ține propria cale și întoarce infinit atunci când întâlnește un flux care se află deja pe ea, deci nu se blochează exact pe intrarea pentru care există verificarea de ciclu. Asta contează fiindcă înseamnă că cele două verificări pot fi rulate în oricare ordine, ceea ce înseamnă că nimeni nu trebuie să țină minte o regulă de ordine.

Adâncimea este păstrată ca o coloană pe rularea-copil, ceea ce este împotriva liniei noastre obișnuite, după care o valoare ce se poate deduce nu este o coloană. Cheia străină către părinte devine nulă atunci când părintele este șters, deci după o ștergere lanțul nu mai poate fi parcurs înapoi ca să fie recalculată. O valoare dedusă a cărei sursă poate să dispară nu se poate deduce.

Ceasul de rezervă este o zi, nu cinci minute

Când o rulare-copil se încheie, pune ora de trezire de pe rândul de așteptare al părintelui pe acum, iar părintele este luat în lucru în zece secunde. Acesta este mecanismul.

Mai există și un ceas de rezervă, pentru cazul în care asta nu se întâmplă: un container care a căzut la jumătatea încheierii copilului, un rând atins cu mâna. Este de douăzeci și patru de ore.

Cinci minute ar fi alegerea instinctivă și este cea greșită. Un copil care stă pe o aprobare poate aștepta pe bună dreptate treizeci de zile. Cu un ceas scurt, părintele s-ar trezi de mii de ori în răstimpul acela ca să constate că nu s-a schimbat nimic, iar fiecare dintre acele treziri este o cerere HTTP de la poartă către containerul web. O zi mărginește paguba unui semnal pierdut la o zi și costă cel mult treizeci de treziri fără rost pe cea mai lungă așteptare pe care o îngăduie sistemul.

O aprobare despre care nu i se spune nimănui este o rulare împotmolită

O cerere de aprobare poate trimite acum un e-mail, iar categoria sub care este trimis este a ei proprie și nu categoria generală de flux. Aceasta a fost o abatere dinadins de la plan.

Categoria generală de flux se duce la toți cei care au modulul de automatizare. O cerere de aprobare ar trebui să se ducă la oamenii care o pot hotărî cu adevărat, ceea ce este o mulțime diferită și mai mică. Așa că există o a doua sită pe categorie: notificarea este livrată numai membrilor care dețin dreptul de a hotărî.

Măsurat pe organizația noastră de test: categoria generală de flux s-a rezolvat către trei destinatari, iar categoria de aprobare către doi. Două numere care diferă sunt întreaga dovadă că sita face ceva.

Un clic care nu a selectat nimic

Învățătura de măsurare a rundei acesteia este despre testul de browser și nu despre produs.

Ajutorul nostru de browser are o metodă de clic care trimite o apăsare de maus și o eliberare de maus. Pe un buton obișnuit, asta funcționează. Pe un nod din pânza de flux nu face absolut nimic: panoul de proprietăți a rămas pe nodul declanșator, iar lista derulantă pe care voiam să o schimbăm nu exista, ceea ce se citește exact ca o funcție lipsă.

Pânza pornește o tragere la coborârea indicatorului și apelează setPointerCapture pe nod. Fără un eveniment de mișcare a mausului înainte și fără câmpul buttons pus pe apăsare, browserul nu produce un clic pe care calea de captură să îl recunoască. Adăugarea acestor două lucruri face selecția să fie imediată.

Mai există un al doilea amănunt în același ajutor. Nu apăsați pe mijlocul unui nod. Mijlocul unui nod cu porturi stă între punctele porturilor, iar acestea au propriul lor tratant de indicator, pentru tragerea unui fir în afară. Apăsați în schimb pe colțul din stânga sus al antetului.

Amândouă arată ca niște defecte de produs atunci când dați peste ele, și niciunul nu este. Aceasta este forma generală a problemei: o simulare de intrare care este aproape corectă eșuează într-un fel cu neputință de deosebit de faptul că lucrul pe care încercați să îl testați ar fi stricat.

Ce am consemna

  1. Un prag bate o bifă atunci când valoarea corectă a bifei este mereu aceeași. Întrebați când ar stinge-o cineva; dacă nu există răspuns, nu construiți comutatorul.
  2. Măsurați pragul față de bugetul în care trebuie să încapă, nu față de funcția pe care o limitați.
  3. Nu puneți pragul nou la vechea limită doar fiindcă atunci nu se schimbă nimic. Faptul că nu se schimbă nimic este chiar problema pe care o rezolvați.
  4. Un ciclu și un lanț prea lung sunt erori diferite. Un singur mesaj pentru amândouă trimite oamenii în locul greșit.
  5. Validați la salvare pentru mesaj și la execuție pentru garanție. Înregistrările vecine se schimbă fără să o revalideze pe a voastră.
  6. O căutare care se încheie pe propria cale poate fi rulată în orice ordine față de verificarea pe care o sprijină, ceea ce înlătură o regulă de ordine pe care nu ar ține-o minte nimeni.
  7. O valoare dedusă a cărei sursă poate fi ștearsă nu este dedusă. Păstrați-o.
  8. Măsurați un ceas de rezervă față de cea mai lungă așteptare îndreptățită, nu față de cât de repede ați vrea să observați.
  9. Îndrumați o notificare după cine poate să acționeze pe temeiul ei, nu după modulul de care ține.
  10. O intrare simulată care este aproape corectă eșuează ca o funcție stricată. Verificați cum primește componenta cu adevărat evenimentele înainte să credeți rezultatul.

Ca să fie limpede ce este aceasta: verificarea de îmbinare a rulat 16 din 16 pași fără nicio linie de eșec, suita web a fost 4583 verde, suitele de pachete, de poartă și de unelte 7286 verde, testele de parcurgere 75 verde, verificările de subflux 13 verde, rularea cap la cap față de baza de date de dezvoltare 58 verde, măsurătoarea destinatarilor 4 verde, iar testul de browser 31 verde cu un lucrător de poartă adevărat, în care o pauză de nouăzeci de secunde a fost reluată după nouăzeci și cinci de secunde, o rulare-părinte și una-copil au fost legate, a fost trimis exact un e-mail de aprobare, iar un lanț de patru și o referință recursivă au fost amândouă refuzate, cu lanțul vinovat numit în mesaj. Testul de editor a fost 9 verde, iar baleiajul de accesibilitate nu a găsit nimic pe șase pagini. Nedovedite: ramurile de epuizare a încercărilor și de revendicare învechită, ceasul de rezervă de douăzeci și patru de ore, un subflux dinăuntrul unei bucle, o rulare-copil dispărută, e-mailul către cineva care nu este proprietar printr-o trimitere adevărată și absolut nimic față de un hipervizor adevărat.

Din munca de platformă la Provibr. Cum a învățat parcurgerea să se oprească, în primul rând, se află în fiecare autoapel era în poziție de coadă, iar forma grafului însuși se află în un flux este un graf, iar el trebuie să fie finit.

Începeți cu o gazdă și un agent

Creați un cont, instalați agentul cu o singură comandă și conectați primul dumneavoastră host Proxmox. Perioada de probă durează 14 zile și nu cere date de plată.