portaldacalheta.pt
  • Põhiline
  • Veebi Kasutajaliides
  • Ui Disain
  • Andmeteadus Ja Andmebaasid
  • Vilgas
Tagumine Ots

Ajatempli kärpimine: Ruby on Rails ActiveRecord Tale



Testid peaksid aitama vältida rakenduste ebakindlust. Kuid aeg-ajalt võivad testid ise muutuda ketendavaks - ka kõige otsesemad. Siit saate teada, kuidas a Rubiin rööbastel rakenduse, mida toetab PostgreSQL, ja mida me avastasime.

Tahtsime kontrollida, et teatud äriloogika (mida kutsutakse meetodiga perform) ei muuda a calendar mudel (Calendar eksemplar, Ruby on Rails ActiveRecordi mudeli klass), nii et kirjutasime:



let(:calendar) { create(:calendar) } specify do expect do perform # call the business action calendar.reload end .not_to change(calendar, :attributes) end

See möödus ühes arenduskeskkonnas (MacOS), kuid CI-s (Linux) oli see peaaegu alati ebaõnnestunud.



Õnneks õnnestus meil see reprodutseerida teises arenduskeskkonnas (Linux), kus see ebaõnnestus sõnumiga:



expected `Calendar#attributes` not to have changed, but did change from {'calendar_auth_id'=>8, 'created_at'=>2020-01-02 13:36:22.459149334 +0000, 'enabled'=>false, 'events_...t_sync_token'=>nil, 'title'=>nil, 'updated_at'=>2020-01-02 13:36:22.459149334 +0000, 'user_id'=>100} to { 'calendar_auth_id'=>8, 'created_at'=>2020-01-02 13:36:22.459149000 +0000, 'enabled'=>false, 'events_...t_sync_token'=>nil, 'title'=>nil, 'updated_at'=>2020-01-02 13:36:22.459149000 +0000, 'user_id'=>100}

Kas näete midagi kahtlast?

Uurimine

Lähemal uurimisel märkasime, et created_at ja updated_at ajatemplid muudeti expect sees veidi plokk:



{'created_at'=>2020-01-02 13:36:22.459149334 +0000, 'updated_at'=>2020-01-02 13:36:22.459149334 +0000} {'created_at'=>2020-01-02 13:36:22.459149000 +0000, 'updated_at'=>2020-01-02 13:36:22.459149000 +0000}

Sekundite osaosa kärbiti nii, et 13:36:22.459149334 sai 13:36:22.459149000.

Olime kindlad, et perform ei värskendanud calendar objekt, seega koostasime hüpoteesi, et ajatemplid kärbiti andmebaasi abil. Selle testimiseks kasutasime teadaolevalt kõige arenenumat silumisvõtet, s.t. paneb silumise :



let(:calendar) { create(:calendar) } specify do expect do puts 'before perform: #{calendar.created_at.to_f}' perform puts 'after perform: #{calendar.created_at.to_f}' calendar.reload puts 'after reload: #{calendar.created_at.to_f}' end .not_to change(calendar, :attributes) end

Kuid kärpimine ei olnud väljundis nähtav:

before perform: 1577983568.550754 after perform: 1577983568.550754 after reload: 1577983568.550754

See oli üsna üllatav - lisavarustus #created_at oleks pidanud olema sama väärtus kui atribuudi räsiväärtus attributes['created_at'] Et olla kindel, et printisime väites kasutatud sama väärtust, muutsime juurdepääsu meetodit created_at



Aksessori calendar.created_at.to_f kasutamise asemel läksime üle selle otsimisele otse atribuutide räsist: calendar.attributes['created_at'].to_f. Meie kahtlused calendar.reload suhtes kinnitati!

before perform: 1577985089.0547702 after perform: 1577985089.0547702 after reload: 1577985089.05477

Nagu näete, helistades perform ei muutnud created_at, kuid reload tegi.



Veendumaks, et muudatus ei toimu mõnes muus calendar eksemplaris ja siis olles päästetud, tegime veel ühe katse. Laadisime uuesti calendar enne testi:

let(:calendar) { create(:calendar).reload } specify do expect do perform calendar.reload end .not_to change(calendar, :attributes) end

See muutis testi roheliseks.



Parandus

Teades, et andmebaas kärbib meie ajatemplid ja ebaõnnestub testide tegemine, otsustasime kärpimise ära hoida. Lõime DateTime objekt ja ümardas selle tervete sekunditeni. Seejärel kasutasime seda objekti Railsi aktiivse kirje ajatemplite selgesõnaliseks määramiseks. See muudatus fikseeris ja stabiliseeris testid:

let(:time) { 1.day.ago.round } let(:calendar) { create(:calendar, created_at: time, updated_at: time) } specify do expect do perform calendar.reload end .not_to change(calendar, :attributes) end

Põhjus

Miks see juhtus? Aktiivse kirje ajatemplid on rööbaste poolt seatud ’ActiveRecord::Timestamp moodul kasutades Time.now . Time täpsus on OS-st sõltuv ja nagu dokumentides öeldakse, võib sisaldada murdosa sekundeid .

Testisime Time.now eraldusvõime MacOS-is ja Linuxis koos skriptiga, mis loeb osade pikkuste sagedusi:

pry> 10000.times.map { Time.now.to_f.to_s.match(/.(d+)/)[1].size }.group_bya.map [k, v.count].to_h # MacOS => {6=>6581, 7=>2682, 5=>662, 4=>67, 3=>7, 2=>1} # Linux => {6=>2399, 7=>7300, 5=>266, 4=>32, 3=>3}

Nagu näete, oli umbes 70% Linuxi ajatemplitest pärast kümnendkohtade täpsust seitse numbrit, MacOS-is ainult 25%. See on põhjus, miks testid läbisid suurema osa ajast MacOS-is ja ebaõnnestusid enamasti Linuxis. Võib-olla olete märganud, et testväljundil oli üheksakohaline täpsus - seda seetõttu, et RSpec kasutab Time#nsec ajaväljundi vormindamiseks.

Kui Railsi mudelid salvestatakse andmebaasi, salvestatakse kõik nende ajatemplid PostgreSQL-i tüüpi nimega timestamp without time zone, mis on mikrosekundiline eraldusvõime - st kuus numbrit pärast koma. Niisiis, kui 1577987974.6472975 saadetakse PostgreSQL-i, see kärbib murdosa viimase numbri ja salvestab selle asemel 1577987974.647297

Küsimused

Ikka on küsimus, miks calendar.created_at ei laaditud uuesti, kui helistasime calendar.reload, kuigi calendar.attributes['created_at'] laaditi uuesti.

kuidas koguda Twitteri andmeid

Samuti on Time täpsuskatse on natuke üllatav. Eeldasime, et MacOS-is on maksimaalne täpsus kuus. Me ei tea, miks see nii on mõnikord on seitse numbrit. Mis üllatas meid rohkem, oli viimaste numbrite väärtuse jaotus:

pry> 10000.times.map { Time.now}.map t.to_f.to_s.match(/.(d+)/)[1] .select.group_bye.map [k, v.size].to_h # MacOS => {'9'=>536, '1'=>555, '2'=>778, '8'=>807} # Linux => {'5'=>981, '1'=>311, '3'=>1039, '9'=>309, '8'=>989, '6'=>1031, '2'=>979, '7'=>966, '4'=>978}

Nagu näete, on MacOS-i seitsmes number alati 1, 2, 8 või 9.

Kui teate vastust mõlemale küsimusele, jagage palun meiega selgitust.

Tulevik

Asjaolu, et Ruby on Rails ’ Aktiivne kirje Rakenduse poolel genereeritud ajatemplid võivad kahjustada ka seda, kui neid ajatempleid kasutatakse andmebaasi salvestatud sündmuste usaldusväärseks ja täpseks järjestamiseks. Kuna rakendusserveri kellad võidakse desünkroonida, järjestavad sündmused created_at võivad ilmuda teistsuguses järjekorras kui need tegelikult aset leidsid. Saada usaldusväärsem käitumine , oleks parem lasta andmebaasiserveril ajatemplid käsitseda (nt PostgreSQL-id now() ).

See on aga lugu, mis on väärt teist artiklit.


Eriline tänu Gabriele Renzi selle artikli loomisel aitamise eest.

Põhitõdede mõistmine

Mis on rubriigis ActiveRecord?

ActiveRecord on objektide-seoste kaardistamise teek, mille pakub Ruby on Rails. See võimaldab teil objekte andmebaasis säilitada, seejärel salvestatud andmeid hankida ja objekte kiirendada.

Mis on Active Recordi juurutamine?

Active Record on ettevõtte arhitektuurimuster, mida kasutatakse relatsioonide andmebaasides mälus olevate objektide püsimiseks. Rakenduse Ruby on Rails rakenduses jälgib ActiveRecord muudatusi Railsi mudeli atribuutides. Mudeli salvestamisel saadab ActiveRecord muudatused koos vajalike ajatemplitega andmebaasi.

Miks on ajatempel oluline?

Vaikimisi salvestab ActiveRecord kaks ajatemplit: created_at (aeg, mil mudel esmakordselt salvestati) ja updated_at (aeg, mil mudel viimati salvestati). Need pakuvad põhilisi auditivõimalusi ja võimaldavad rakendustel sorteerida mudeleid alates uusimatest või viimati uuendatud mudelitest.

Mis on ajatempel PostgreSQL-is?

Ajatempel on PostgreSQL-i andmetüüp, mis salvestab nii kuupäeva kui ka kellaaega. Selle eraldusvõime ja täpsus on ühe mikrosekundiga, mis tähendab, et see hoiab sekundite murdosa kuni kuus numbrit.

Mis andmebaasi Ruby on Rails kasutab?

Ruby on Rails võimaldab arendajatel kasutada enamikku populaarsetest andmebaasidest. Vaikimisi kasutab Ruby on Rails teeki ActiveRecord, mis toetab DB2, Firebird, FrontBase, MySQL, OpenBase, Oracle, PostgreSQL, SQLite, Microsoft SQL Server ja Sybase.

Flexboxi ja Sass Gridi õpetus: kuidas sujuvamaks muuta tundlikku disaini

Veebi Kasutajaliides

Flexboxi ja Sass Gridi õpetus: kuidas sujuvamaks muuta tundlikku disaini
Logo ajalugu 101 - ülevaade kestvatest muljetest

Logo ajalugu 101 - ülevaade kestvatest muljetest

Brändikujundus

Lemmik Postitused
Raha kogumise pigi teki kunst
Raha kogumise pigi teki kunst
Amazon vs. Walmart: Bezos läheb kogu toiduainete omandamisega jugulaarseks
Amazon vs. Walmart: Bezos läheb kogu toiduainete omandamisega jugulaarseks
Bootstrapped: kaugettevõtte ehitamine
Bootstrapped: kaugettevõtte ehitamine
Bootstrapi kasutamine ja .NET-projektide loomine
Bootstrapi kasutamine ja .NET-projektide loomine
Kuidas luua meilisõnumite analüüsi bot: NLP-õpetus.
Kuidas luua meilisõnumite analüüsi bot: NLP-õpetus.
 
Kommunikatsioonidirektor
Kommunikatsioonidirektor
Kuidas vältida funktsioonide libisemist kasutajalugude parimate tavade abil
Kuidas vältida funktsioonide libisemist kasutajalugude parimate tavade abil
Täpsem Git-juhend: Git Stash, Reset, Rebase ja palju muud
Täpsem Git-juhend: Git Stash, Reset, Rebase ja palju muud
Disainihariduse tähtsus
Disainihariduse tähtsus
KPI-d edu saavutamiseks - ülevaade projektijuhi jõudlusmõõdikutest
KPI-d edu saavutamiseks - ülevaade projektijuhi jõudlusmõõdikutest
Lemmik Postitused
  • millist neist ei arvestata mobiilseadme e-kirjade vastuvõtmiseks seadistamisel?
  • on scala raske õppida
  • mis on veebidisainis alglaadimine
  • Värvi psühholoogiline mõju inimese käitumisele
  • node js vs java jõudlus
Kategooriad
  • Veebi Kasutajaliides
  • Ui Disain
  • Andmeteadus Ja Andmebaasid
  • Vilgas
  • © 2022 | Kõik Õigused Kaitstud

    portaldacalheta.pt