Im Fintech-Bereich mĂŒssen wir oft ziemlich groĂe Datenmengen zu Wechselkursen verarbeiten. Wir erhalten Daten aus verschiedenen Quellen, und jede von ihnen hat ihre eigene Auffassung darĂŒber, wie Werte fĂŒr die Kurse von morgen, ĂŒbermorgen, nĂ€chsten Monat und sogar in den nĂ€chsten drei Jahren extrapoliert werden sollen. Wenn jemand in der Lage wĂ€re, Kurse vorherzusagen, wĂ€re es an der Zeit, das GeschĂ€ft zu schlieĂen und einfach Geld hin und her zu tauschen. es wichtig,Einige Quellen genieĂen mehr Vertrauen, andere liefern nur MĂŒll, seltene EinschĂŒbe mit fast richtigen Werten, aber dafĂŒr fĂŒr exotische Paare. Unsere Aufgabe besteht darin, diese zigtausend Werte pro Sekunde zu filtern und zu bestimmen, was genau den Kunden gezeigt werden soll. Wir mĂŒssen den einzigen richtigen Wert aus Tonnen von Schmutz und Schlamm herausfiltern, wie das Flamingos beim Essen tun.

Ein charakteristisches Merkmal von Flamingos ist der massive, nach unten gebogene Schnabel, mit dem sie Nahrung aus Wasser oder Schlamm filtern.
 âÂ
So entstand die Bibliothek , die einen Cache von ZustĂ€nden fĂŒr mehrere Werte in vorgegebenen Zeitintervallen speichert. Im Hintergrund filtert sie in Echtzeit schlechte und veraltete Daten heraus und bietet Zugang zu den letzten N gĂŒltigen Werten fĂŒr jeden SchlĂŒssel (WĂ€hrungspaare, in unserem Fall).
Angenommen, wir sammeln Kurse fĂŒr drei WĂ€hrungspaare. Die einfachste Definition Vela zur Speicherung des aktuellen Status wĂŒrde etwa so aussehen:
defmodule Pairs do
use Vela,
eurusd: [sorter: &Kernel. 0
endAktualisierung der Werte
Die Funktion wird der Reihe nach Folgendes tun:
- sie wird den
Validatorauf dem Wert aufrufen, wenn er definiert ist (siehe Kapitel Validierung unten); - sie fĂŒgt den Wert entweder in die Reihe der guten Werte hinzu, wenn die Validierung erfolgreich war, oder in die Hilfsreihe
:__errors__im anderen Fall; - sie wird die Sortierung aufrufen, wenn ein
SorterfĂŒr diesen SchlĂŒssel definiert ist, oder legt den Wert einfach an den Kopf der Liste (LIFO, siehe Kapitel Sortierung unten); - schneidet die Reihe gemÀà dem Parameter
:limitab, der bei der Erstellung ĂŒbergeben wurde; - sie gibt die aktualisierte Struktur zurĂŒck.
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]}AuĂerdem Vela implementiert , sodass jede der Standardfunktionen fĂŒr die tiefe Aktualisierung von Strukturen genutzt werden kann : , , , , und .
Validierung
Der Validator kann definiert werden als:
- eine externe Funktion mit einem Argument (
&MyMod.my_fun/1), sie erhÀlt nur den Wert zur Validierung; - eine externe Funktion mit zwei Argumenten,
&MyMod.my_fun/2, sie erhÀlt das Paarserie, valuezur Validierung; - ein Modul, das implementiert ;
- Konfigurationsparameter
Schwellenwert, und â optional âcompare_by, siehe Kapitel Vergleich darunter.
Wenn die Validierung erfolgreich war, wird der Wert unter dem entsprechenden SchlĂŒssel zur Liste hinzugefĂŒgt, andernfalls wird das Tupel {serie, value} an :__errors_.
Vergleich
Werte, die in diesen Reihen gespeichert werden, können beliebig sein. Um zu lernen, Vela sie zu vergleichen, muss compare_by ein Parameter in die Definition der Reihe ĂŒbergeben werden (es sei denn, die Werte können mit dem Standard Kernel.</2); dieser Parameter sollte den Typ haben (Vela.value() -> number()). StandardmĂ€Ăig ist dies einfach & &1.
ZusĂ€tzlich kann zur Definition der Reihe ein Parameter comparator fĂŒr die Berechnung der Delta-Werte ĂŒbergeben werden (min/max); beispielsweise kann man durch das Ăbergeben von Date.diff/2 als Comparator korrekte Deltas fĂŒr Daten erhalten.
Eine weitere bequeme Möglichkeit ist die Ăbergabe eines Parameters, Schwellenwertder das maximal zulĂ€ssige VerhĂ€ltnis des neuen Wertes zu {min, max} intervall definiert. Da dies in Prozent angegeben ist, nutzt die ĂberprĂŒfung nicht comparator, verwendet aber immer noch compare_by. Beispielsweise muss, um einen Schwellenwert fĂŒr Datumswerte anzugeben, compare_by: &DateTime.to_unix/1 (um einen ganzzahligen Wert zu erhalten) und threshold: 1, damit neue Werte nur erlaubt sind, wenn sie sich im ±band Intervall der aktuellen Werte befinden.
SchlieĂlich kann man Vela.equal?/2 zum Vergleichen zweier Caches verwenden. Wenn die Werte die Funktion equal?/2 oder compare/2, dann werden diese Funktionen fĂŒr den Vergleich verwendet, andernfalls verwenden wir einfach ==/2.
Werte abrufen
Die Verarbeitung des aktuellen Zustands beginnt normalerweise mit dem Aufruf Vela.purge/1, der veraltete Werte entfernt (wenn Validator mit timestamps). Dann kann man Vela.slice/1, die zurĂŒckgibt keyword mit den Namen der Reihen als SchlĂŒsseln und den ersten, aktuellen Werten.
Es kann auch genutzt werden get_in/2/pop_in/2 fĂŒr den Zugriff auf Werte in jeder Reihe auf niedriger Ebene.
Anwendung
Vela kann sich als Ă€uĂerst nĂŒtzlich als Cache fĂŒr Zeitreihen im Zustand eines Prozess-Typs erweisen GenServer/Agent. Wir möchten niemals veraltete Kurswerte verwenden, und dazu halten wir einfach einen Prozess mit einem Zustand, der von Vela, mit dem Validator, der unten gezeigt wird, verarbeitet wird.
@impl Vela.Validator
def valid?(_key, %Rate{} = rate),
do: Rate.age(rate) < @death_ageund Vela.purge/1 der alle veralteten Werte jedes Mal entfernt, wenn wir Daten benötigen. FĂŒr den Zugriff auf die aktuellen Werte rufen wir einfach Vela.slice/1, und wenn eine kleine Historie des Kurses benötigt wird (die gesamte Reihe), geben wir sie einfach zurĂŒck â bereits sortiert â mit validierten Werten.
Viel Erfolg beim Caching von Zeitreihen!
Quelle: habr.com
