Vela → zaman serileri ve daha fazlası için akıllı önbellek

Fintech'te genellikle oldukça büyük miktarlarda döviz kuru verilerini işlemek zorunda kalıyoruz. Farklı kaynaklardan veri alıyoruz ve her birinin yarın, yarından sonraki gün, gelecek ay ve hatta önümüzdeki üç yıl için döviz kurlarını nasıl tahmin edeceğine dair kendi fikirleri var. Keşke birisi oranları tahmin edebilseydi doğru, işi kapatmanın ve aptalca parayı ileri geri değiştirmenin zamanı gelmişti. Bazı kaynaklar daha güvenilirdir, bazıları ise neredeyse doğru değerlere sahip nadir eklemelerle tam bir çöp sağlar, ancak egzotik çiftler için. Bizim işimiz saniyede bu onbinlerce değeri elemek ve müşterilere tam olarak neyi göstereceğimizi belirlemek. Tıpkı flamingoların öğle yemeğinde yaptığı gibi, tonlarca kir ve çamurun içinden tek doğru değeri filtrelememiz gerekiyor.

Vela → zaman serileri ve daha fazlası için akıllı önbellek

Flamingoların özel bir ayırt edici özelliği, yiyecekleri sudan veya çamurdan filtreledikleri, aşağıya doğru kavisli devasa gagalarıdır.
 - Wiki

Böylece kütüphane doğdu VelaBelirtilen zaman aralıklarında birden çok değer için durum önbelleğini depolayan. Temel olarak, kötü ve güncel olmayan verileri anında filtreler ve aynı zamanda en son sürümlere erişim sağlar. N her anahtar için doğrulanmış değerler (bizim durumumuzda döviz çiftleri).

Diyelim ki üç döviz çifti için oranları topladık. En basit tanım Vela mevcut durumu saklamak için şuna benzer:

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

Değerler Güncelleniyor

Vela.put/3 Fonksiyon sırayla şunları yapacaktır:

  • sebep olacak validator tanımlanmışsa değer üzerinde (bkz. bölüm Doğrulama altında);
  • doğrulama başarılı olursa değeri iyi değerler satırına veya hizmet satırına ekleyecektir :__errors__ aksi takdirde;
  • eğer sıralamaya neden olur sorter belirli bir anahtar için tanımlanır veya değeri listenin başına koyar (LIFO, bölüme bakın Сортировка altında);
  • satırı parametreye göre kırpacak :limit yaradılıştan aktarılan;
  • güncellenmiş yapıyı döndürecek 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]}

Ayrıca Vela uygular Access, böylece değerleri güncellemek için cephanelikteki yapıların derinlemesine güncellenmesine yönelik standart işlevlerden herhangi birini kullanabilirsiniz. Kernel: Kernel.get_in/2, Kernel.put_in/3, Kernel.update_in/3, Kernel.pop_in/2, ve Kernel.get_and_update_in/3.

Doğrulama

Doğrulayıcı şu şekilde tanımlanabilir:

  • tek argümanlı harici fonksiyon (&MyMod.my_fun/1), yalnızca doğrulama için değeri alacaktır;
  • iki argümanlı harici fonksiyon, &MyMod.my_fun/2, bir çift alacak serie, value doğrulama için;
  • modül uygulama Vela.Validator;
  • konfigürasyon parametresi thresholdve - isteğe bağlı olarak - compare_by, bölüme bakın karşılaştırma Aşağıda.

Doğrulama başarılı olursa değer, ilgili anahtarın altındaki listeye eklenir, aksi takdirde tanımlama grubu; {serie, value} gönderilmemiş :__errors_.

Karşılaştırma

Bu satırlarda saklanan değerler herhangi bir şey olabilir. Öğretmek Vela bunları karşılaştırmak için aktarmak gerekir compare_by seri tanımındaki parametre (değerler standartla karşılaştırılamadığı sürece) Kernel.</2); bu parametre şu türden olmalıdır: (Vela.value() -> number()). Varsayılan olarak basittir & &1.

Ayrıca satır tanımına bir parametre iletebilirsiniz. comparator delta değerlerini hesaplamak için (min/max); örneğin ileterek Date.diff/2 karşılaştırıcı olarak tarihler için doğru deltaları alabilirsiniz.

Çalışmanın bir başka kolay yolu da bir parametre iletmektir thresholdYeni değerin izin verilen maksimum oranını tanımlayan {min, max} aralık. Yüzde olarak belirtildiği için çek kullanılmaz. comparatorama hala kullanıyor compare_by. Örneğin, tarih saatleri için bir eşik değeri belirlemek amacıyla şunu belirtmeniz gerekir: compare_by: &DateTime.to_unix/1 (bir tamsayı değeri elde etmek için) ve threshold: 1yeni değerlere yalnızca içinde olmaları durumunda izin verilmesine neden olur ±band mevcut değerlerden aralık.

Son olarak, kullanabilirsiniz Vela.equal?/2 iki önbelleği karşılaştırmak için. Değerler bir işlevi tanımlıyorsa equal?/2 veya compare/2, o zaman bu işlevler karşılaştırma için kullanılacaktır, aksi takdirde aptalca kullanırız ==/2.

Değerleri alma

Mevcut durumun işlenmesi genellikle aramayla başlar Vela.purge/1, eski değerleri kaldıran (eğer validator bağlı timestamps). Daha sonra arayabilirsiniz Vela.slice/1hangisi geri dönecek keyword anahtar olarak satır adları ve ilk gerçek değerler.

Ayrıca kullanabilirsiniz get_in/2/pop_in/2 her satırdaki değerlere düşük düzeyde erişim için.

uygulama

Vela gibi bir işlem durumunda zaman serisi önbelleği olarak son derece yararlı olabilir GenServer/Agent. Eski kurs değerlerini asla kullanmak istemiyoruz ve bunu yapmak için süreci durum işlenmiş halde tutuyoruz Vela, aşağıda gösterilen doğrulayıcıyla.

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

и Vela.purge/1 Verilere her ihtiyaç duyduğumuzda tüm eski değerleri sessizce kaldırır. Gerçek değerlere erişmek için basitçe çağırıyoruz Vela.slice/1ve kursun küçük bir geçmişi gerektiğinde (tüm seri), doğrulanmış değerlerle zaten sıralanmış olarak geri döndürürüz.

Mutlu zaman serisi önbellekleme!

Kaynak: habr.com

Yorum ekle