Vela → cache inteligentă pentru serii cronologice și multe altele
În fintech, trebuie adesea să procesăm volume destul de masive de date privind cursul de schimb valutar. Obținem date din diferite surse și fiecare dintre ele are propria idee despre cum să extrapolăm cursurile de schimb pentru mâine, poimâine, luna viitoare și chiar următorii trei ani. Dacă cineva ar putea prezice ratele corect, ar fi timpul să închidem afacerea și să schimbăm prostesc banii înainte și înapoi. Unele surse sunt mai de încredere, unele furnizează gunoi complet, cu includeri rare de valori aproape corecte, dar pentru cuplurile exotice. Sarcina noastră este să cercetăm aceste zeci de mii de valori pe secundă și să stabilim ce anume să arătăm clienților. Trebuie să filtram singura valoare corectă din tone de murdărie și nămol, la fel cum fac flamingii la prânz.
O trăsătură distinctivă specială a flamingo este ciocul lor masiv curbat în jos, cu care filtrează alimentele din apă sau noroi.
- Vicki
Astfel s-a născut biblioteca Vela, care stochează un cache de stare pentru mai multe valori la intervale de timp specificate. Sub capotă, filtrează din mers datele proaste și învechite și oferă, de asemenea, acces la cele mai recente N valori validate pentru fiecare cheie (perechi valutare, în cazul nostru).
Să presupunem că colectăm rate pentru trei perechi valutare. Cea mai simplă definiție Vela pentru a stoca starea curentă va arăta cam așa:
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
Actualizarea valorilor
Vela.put/3 Funcția va face următoarele în secvență:
va cauza validator asupra valorii, dacă este definită una (vezi capitolul Validare de mai jos);
va adăuga valoarea fie la rândul de valori bune dacă validarea a avut succes, fie la rândul de servicii :__errors__ in caz contrar;
va provoca sortarea dacă sorter definit pentru o anumită cheie sau pur și simplu va pune valoarea în capul listei (LIFO, vezi capitolul triere de mai jos);
va tăia rândul conform parametrului :limit transmis la creație;
parametrul de configurare thresholdși - opțional - compare_by, vezi capitolul Comparaţie de mai jos.
Dacă validarea are succes, valoarea este adăugată la listă sub cheia corespunzătoare, în caz contrar, tuplu {serie, value} se duce la :__errors_.
comparație
Valorile stocate în aceste rânduri pot fi orice. A invata Vela pentru a le compara, este necesar să se transfere compare_by parametrul în definiția seriei (cu excepția cazului în care valorile nu pot fi comparate cu standardul Kernel.</2); acest parametru trebuie să fie de tip (Vela.value() -> number()). Implicit este simplu & &1.
De asemenea, puteți trece un parametru definiției rândului comparator pentru a calcula valorile delta (min/max); de exemplu prin transmitere Date.diff/2 ca comparator, puteți obține deltele corecte pentru date.
Un alt mod convenabil de a lucra este să treci un parametru threshold, care definește raportul maxim permis al noii valori la {min, max} interval. Deoarece este specificat ca procent, cecul nu folosește comparatordar încă folosește compare_by. De exemplu, pentru a specifica o valoare de prag pentru data orelor, trebuie să specificați compare_by: &DateTime.to_unix/1 (pentru a obține o valoare întreagă) și threshold: 1, ceea ce face ca noile valori să fie permise numai dacă sunt în ±band interval de la valorile curente.
În sfârșit, puteți folosi Vela.equal?/2 pentru a compara două cache-uri. Dacă valorile definesc o funcție equal?/2 sau compare/2, atunci aceste funcții vor fi folosite pentru comparație, altfel folosim prostește ==/2.
Obținerea de valori
Procesarea stării curente începe de obicei cu un apel Vela.purge/1, care elimină valorile învechite (dacă validator legat de timestamps). Apoi puteți suna Vela.slice/1care se va întoarce keyword cu nume de rând ca chei și primele valori reale.
Puteți utiliza, de asemenea get_in/2/pop_in/2 pentru acces la nivel scăzut la valorile din fiecare rând.
App
Vela poate fi extrem de util ca cache de serie de timp într-o stare de proces cum ar fi GenServer/Agent. Vrem să nu folosim niciodată valori de curs învechite și pentru a face acest lucru pur și simplu păstrăm procesul cu starea procesată Vela, cu validatorul prezentat mai jos.
и Vela.purge/1 elimină în liniște toate valorile învechite de fiecare dată când avem nevoie de date. Pentru a accesa valorile reale, sunăm pur și simplu Vela.slice/1, iar când este necesar un mic istoric al cursului (întreaga serie), pur și simplu îl returnăm - deja sortat - cu valori validate.