Vela → cache inteligjente për seritë kohore dhe më shumë

Në fintech, shpesh na duhet të përpunojmë vëllime mjaft masive të të dhënave të kursit të këmbimit të monedhës. Ne marrim të dhëna nga burime të ndryshme dhe secila prej tyre ka idenë e vet se si të ekstrapolojmë kurset e këmbimit për nesër, pasnesër, muajin tjetër dhe madje edhe tre vitet e ardhshme. Nëse dikush mund të parashikonte tarifat korrekt, do të ishte koha për të mbyllur biznesin dhe thjesht për të ndryshuar para e me radhë paratë. Disa burime janë më të besueshme, disa furnizojnë mbeturina të plota, me përfshirje të rralla të vlerave pothuajse të sakta, por për çifte ekzotike. Detyra jonë është të analizojmë këto dhjetëra mijëra vlera në sekondë dhe të përcaktojmë se çfarë saktësisht t'u tregojmë klientëve. Ne duhet të filtrojmë vlerën e vetme të saktë nga tonelatat e papastërtive dhe baltës, ashtu siç bëjnë flamingot në drekë.

Vela → cache inteligjente për seritë kohore dhe më shumë

Një tipar i veçantë dallues i flamingove është sqepi i tyre masiv i lakuar poshtë, me të cilin ata filtrojnë ushqimin nga uji ose balta.
 - Vicki

Kështu lindi biblioteka Vela, i cili ruan një cache të gjendjes për vlera të shumta në intervale kohore të specifikuara. Nën kapuç, ai filtron të dhënat e këqija dhe të vjetruara në fluturim, dhe gjithashtu ofron qasje në më të fundit N vlerat e vërtetuara për çdo çelës (çiftet e monedhës, në rastin tonë).

Le të themi se mbledhim norma për tre palë monedhash. Përkufizimi më i thjeshtë Vela për të ruajtur gjendjen aktuale do të duket diçka si kjo:

defmodule Pairs do
  use Vela,
    eurusd: [sorter: &Kernel.<=/2],
    eurgbp: [limit: 3, errors: 1],
    eurcad: [validator: Pairs]

  @behaviour Vela.Validator

  @impl Vela.Validator
  def valid?(:eurcad, rate), do: rate > 0
end

Përditësimi i vlerave

Vela.put/3 Funksioni do të bëjë si më poshtë në sekuencë:

  • do të shkaktojë validator mbi vlerën, nëse një është e përcaktuar (shih kapitullin Vlerësimi më poshtë);
  • do të shtojë vlerën ose në rreshtin e vlerave të mira nëse vërtetimi ishte i suksesshëm, ose në rreshtin e shërbimit :__errors__ ndryshe;
  • do të shkaktojë renditjen nëse sorter të përcaktuara për një çelës të caktuar, ose thjesht do të vendosë vlerën në krye të listës (LIFO, shih kapitullin klasifikim më poshtë);
  • do të shkurtojë rreshtin sipas parametrit :limit kaloi pas krijimit;
  • do të kthejë strukturën e përditësuar Vela.

iex|1 > pairs = %Pairs{}
iex|2 > Vela.put(pairs, :eurcad, 1.0)
#⇒ %Pairs{..., eurcad: [1.0], ...}
iex|3 > Vela.put(pairs, :eurcad, -1.0)
#⇒ %Pairs{__errors__: [eurcad: -1.0], ...}
iex|4 > pairs |> Vela.put(:eurusd, 2.0) |> Vela.put(:eurusd, 1.0)
#⇒ %Pairs{... eurusd: [1.0, 2.0]}

Edhe Vela zbaton Access, kështu që mund të përdorni cilindo nga funksionet standarde për përditësimin e thellë të strukturave nga arsenali për të përditësuar vlerat Kernel: Kernel.get_in/2, Kernel.put_in/3, Kernel.update_in/3, Kernel.pop_in/2dhe Kernel.get_and_update_in/3.

Vlerësimi

Një vërtetues mund të përkufizohet si:

  • funksioni i jashtëm me një argument (&MyMod.my_fun/1), do të marrë vetëm vlerën për vërtetim;
  • funksioni i jashtëm me dy argumente, &MyMod.my_fun/2, ajo do të marrë një palë serie, value për vërtetim;
  • implementimi i modulit Vela.Validator;
  • parametri i konfigurimit threshold, dhe - sipas dëshirës - compare_by, shih kapitullin Krahasim më poshtë.

Nëse vërtetimi është i suksesshëm, vlera i shtohet listës nën çelësin përkatës; përndryshe, tupleja {serie, value} shkon në :__errors_.

krahasim

Vlerat e ruajtura në këto rreshta mund të jenë çdo gjë. Për të mësuar Vela për t'i krahasuar ato, është e nevojshme të transferohen compare_by parametër në përkufizimin e serisë (përveç nëse vlerat nuk mund të krahasohen me standardin Kernel.</2); ky parametër duhet të jetë i tipit (Vela.value() -> number()). Si parazgjedhje është e thjeshtë & &1.

Gjithashtu, mund të kaloni një parametër në përkufizimin e rreshtit comparator për të llogaritur vlerat delta (min/max); për shembull, duke transmetuar Date.diff/2 si krahasues, mund të merrni deltat e sakta për datat.

Një mënyrë tjetër e përshtatshme për të punuar është kalimi i një parametri threshold, i cili përcakton raportin maksimal të lejueshëm të vlerës së re me {min, max} intervali. Meqenëse është specifikuar në përqindje, çeku nuk përdoret comparatorpor ende përdor compare_by. Për shembull, për të specifikuar një vlerë pragu për kohën e datës, duhet të specifikoni compare_by: &DateTime.to_unix/1 (për të marrë një vlerë të plotë) dhe threshold: 1, duke bërë që vlerat e reja të lejohen vetëm nëse janë in ±band intervali nga vlerat aktuale.

Më në fund, mund të përdorni Vela.equal?/2 për të krahasuar dy cache. Nëse vlerat përcaktojnë një funksion equal?/2 ose compare/2, atëherë këto funksione do të përdoren për krahasim, përndryshe ne përdorim marrëzi ==/2.

Marrja e vlerave

Përpunimi i gjendjes aktuale zakonisht fillon me thirrjen Vela.purge/1, i cili heq vlerat e vjetruara (nëse validator i lidhur me timestamps). Më pas mund të telefononi Vela.slice/1e cila do të kthehet keyword me emrat e rreshtave si çelësa dhe vlerat e para, aktuale.

Ju gjithashtu mund të përdorni get_in/2/pop_in/2 për qasje të nivelit të ulët në vlerat në çdo rresht.

Aplikim

Vela mund të jetë jashtëzakonisht i dobishëm si një cache e serive kohore në një gjendje procesi si GenServer/Agent. Ne duam të mos përdorim kurrë vlera të ndenjura të kursit dhe për ta bërë këtë ne thjesht e mbajmë procesin me gjendje të përpunuar Vela, me vërtetuesin e treguar më poshtë.

@impl Vela.Validator
def valid?(_key, %Rate{} = rate),
  do: Rate.age(rate) < @death_age

и Vela.purge/1 heq në heshtje të gjitha vlerat bajate sa herë që na duhen të dhënat. Për të hyrë në vlerat aktuale ne thjesht telefonojmë Vela.slice/1, dhe kur kërkohet një historik i vogël i kursit (e gjithë seria), ne thjesht e kthejmë atë - tashmë të renditur - me vlera të vërtetuara.

Gëzuar memorien e serive kohore!

Burimi: www.habr.com

Shto një koment