Vela → cache intelligente per a serie temporale è più

In fintech, spessu avemu da processà volumi abbastanza massivi di dati di scambiu di valuta. Ricevemu dati da diverse fonti, è ognunu hà a so propria idea di cumu extrapolà i tassi di scambiu per dumane, dopu dumani, u mesi dopu è ancu i prossimi trè anni. Se solu qualcunu puderia predice i tassi dirittu, Saria ora di chjude l'affari è solu stupidu cambià soldi avanti è avanti. Certi fonti sò più affidabili, alcuni furnisce basura cumpleta, cù rari inclusi di valori quasi curretti, ma per coppie esotiche. U nostru travagliu hè di vagliate queste decine di millaie di valori per seconda è determinà esattamente ciò chì mostra à i clienti. Avemu bisognu di filtrà l'unicu valore currettu da tunnellate di terra è lima, cum'è i flamingos facenu à u pranzu.

Vela → cache intelligente per a serie temporale è più

Una caratteristica distintiva spiciale di i flamingos hè u so beccu massivu curvatu in u fondu, cù quale filtranu l'alimentu da l'acqua o fangu.
 - Wiki

Hè cusì nata a biblioteca Vela, chì guarda una cache di statu per parechji valori à intervalli di tempu specificati. Sottu u cappucciu, filtra i dati cattivi è obsoleti nantu à a mosca, è furnisce ancu accessu à l'ultime N valori validati per ogni chjave (coppiu di valuta, in u nostru casu).

Diciamu chì cullemu i tassi per trè coppie di valuta. Definizione più simplice Vela per almacenà u statu attuale, sarà cusì cusì:

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

Aghjurnà i valori

Vela.put/3 A funzione farà i seguenti in sequenza:

  • pruvucarà validator nantu à u valore, se unu hè definitu (vede u capitulu Validazione sottu);
  • aghjunghje u valore sia à a fila di boni valori se a validazione hè successu, sia à a fila di serviziu :__errors__ altrimenti;
  • pruvucarà a classificazione se sorter definitu per una chjave data, o si mette solu u valore in capu di a lista (LIFO, vede u capitulu Ordine sottu);
  • trimma a fila secondu u paràmetru :limit passatu nantu à a creazione;
  • restituverà a struttura aghjurnata 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]}

Inoltre Vela implementa Access, cusì pudete aduprà qualsiasi di e funzioni standard per l'aghjurnamentu profondu di strutture da l'arsenale per aghjurnà i valori Kernel: Kernel.get_in/2, Kernel.put_in/3, Kernel.update_in/3, Kernel.pop_in/2, e Kernel.get_and_update_in/3.

Validazione

Un validatore pò esse definitu cum'è:

  • funzione esterna cun un argumentu (&MyMod.my_fun/1), riceverà solu u valore per a validazione;
  • funzione esterna cù dui argumenti, &MyMod.my_fun/2, hà da piglià un paru serie, value per a validazione;
  • implementazione di u modulu Vela.Validator;
  • paràmetru di cunfigurazione threshold, è - optionalmente - compare_by, vede u capitulu paragunà quì sottu.

Se a validazione hè successu, u valore hè aghjuntu à a lista sottu a chjave currispondente; altrimenti, a tupla {serie, value} va à :__errors_.

Comparaison

I valori guardati in queste fila ponu esse qualcosa. Per insignà Vela per paragunà elli, hè necessariu di trasferimentu compare_by paràmetru in a definizione di serie (salvo chì i valori ùn ponu esse paragunati cù u standard Kernel.</2); stu paràmetru deve esse di tipu (Vela.value() -> number()). Per automaticamente, hè simplice & &1.

Inoltre, pudete passà un paràmetru à a definizione di fila comparator per calculà i valori di delta (min/max); per esempiu, trasmettendu Date.diff/2 cum'è un comparatore, pudete uttene u delta currettu per e date.

Un altru modu còmuda di travaglià hè di passà un paràmetru threshold, chì definisce u rapportu massimu permissibile di u novu valore à {min, max} intervallu. Siccomu hè specificatu cum'è un percentinu, u cuntrollu ùn usa micca comparatorma sempre usa compare_by. Per esempiu, per specificà un valore di limitu per i tempi di data, deve esse specificà compare_by: &DateTime.to_unix/1 (per piglià un valore integeru) è threshold: 1, facendu chì i novi valori sò permessi solu s'ellu sò in ±band intervallu da i valori attuali.

Infine, pudete aduprà Vela.equal?/2 per paragunà dui cache. Se i valori definiscenu una funzione equal?/2 o compare/2, allura sti funzioni seranu usati per paragunà, altrimenti usemu stupidu ==/2.

Pigliate i valori

Trattamentu di u statu attuale di solitu principia cù a chjama Vela.purge/1, chì elimina i valori obsoleti (se validator legatu à timestamps). Allora pudete chjamà Vela.slice/1chì tornerà keyword cù nomi di fila cum'è chjave è i primi valori attuali.

Pudete ancu aduprà get_in/2/pop_in/2 per un accessu à livellu bassu à i valori in ogni fila.

Applicazione

Vela pò esse estremamente utile cum'è una cache di serie temporale in un statu di prucessu cum'è GenServer/Agent. Vulemu mai aduprà i valori di corsu stale, è per fà questu avemu solu mantene u prucessu cù statu processatu Vela, cù u validatore mostratu quì sottu.

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

и Vela.purge/1 elimina tranquillamente tutti i valori stantii ogni volta chì avemu bisognu di dati. Per accede à i valori attuali, chjamemu solu Vela.slice/1, è quandu una piccula storia di u corsu hè necessariu (tutta a serie), simpricimenti riturnà - digià ordenatu - cù valori cunvalidati.

Felice caching di serie di tempu!

Source: www.habr.com

Add a comment