Vela β†’ cache pintar untuk deret waktu dan banyak lagi

Di fintech, kita seringkali harus memproses data nilai tukar mata uang dalam jumlah yang cukup besar. Kami mendapatkan data dari berbagai sumber, dan masing-masing memiliki gagasan tersendiri tentang bagaimana melakukan ekstrapolasi nilai tukar untuk besok, lusa, bulan depan, dan bahkan tiga tahun ke depan. Andai saja seseorang bisa memprediksi tarif benar, sudah waktunya untuk menutup bisnis dan dengan bodohnya menukar uang bolak-balik. Beberapa sumber lebih dapat diandalkan, beberapa menyediakan sampah lengkap, dengan penyertaan nilai yang hampir benar yang jarang terjadi, tetapi untuk pasangan yang eksotik. Tugas kita adalah menyaring puluhan ribu nilai per detik ini dan menentukan apa yang sebenarnya ingin ditunjukkan kepada pelanggan. Kita perlu menyaring satu nilai yang benar dari berton-ton kotoran dan lumpur, seperti yang dilakukan flamingo saat makan siang.

Vela β†’ cache pintar untuk deret waktu dan banyak lagi

Ciri khas flamingo adalah paruhnya yang besar dan melengkung ke bawah, yang dengannya mereka menyaring makanan dari air atau lumpur.
 - Wiki

Maka lahirlah perpustakaan Vela, yang menyimpan cache status untuk beberapa nilai pada interval waktu tertentu. Di balik terpalnya, ia memfilter data buruk dan usang dengan cepat, dan juga menyediakan akses ke data terbaru N nilai yang divalidasi untuk setiap kunci (pasangan mata uang, dalam kasus kami).

Katakanlah kita mengumpulkan nilai tukar untuk tiga pasangan mata uang. Definisi paling sederhana Vela untuk menyimpan keadaan saat ini akan terlihat seperti ini:

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

Memperbarui Nilai

Vela.put/3 Fungsi ini akan melakukan hal berikut secara berurutan:

  • akan menyebabkan validator pada nilainya, jika ditentukan (lihat bab Validasi di bawah);
  • akan menambahkan nilai ke baris nilai baik jika validasi berhasil, atau ke baris layanan :__errors__ jika tidak;
  • akan menyebabkan penyortiran jika sorter didefinisikan untuk kunci tertentu, atau hanya akan menempatkan nilai di bagian atas daftar (LIFO, lihat bab Sortir di bawah);
  • akan memangkas baris sesuai dengan parameter :limit diwariskan pada penciptaan;
  • akan mengembalikan struktur yang diperbarui 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]}

Juga Vela mengimplementasikan Access, sehingga Anda dapat menggunakan fungsi standar apa pun untuk memperbarui struktur secara mendalam dari gudang senjata untuk memperbarui nilai Kernel: Kernel.get_in/2, Kernel.put_in/3, Kernel.update_in/3, Kernel.pop_in/2, dan Kernel.get_and_update_in/3.

Validasi

Validator dapat didefinisikan sebagai:

  • fungsi eksternal dengan satu argumen (&MyMod.my_fun/1), ia hanya akan menerima nilai untuk validasi;
  • fungsi eksternal dengan dua argumen, &MyMod.my_fun/2, dia akan mendapatkan sepasang serie, value untuk validasi;
  • implementasi modul Vela.Validator;
  • parameter konfigurasi threshold, dan - secara opsional - compare_by, lihat bab Perbandingan di bawah.

Jika validasi berhasil, nilai ditambahkan ke daftar di bawah kunci yang sesuai; jika tidak, tupel {serie, value} dikirim ke :__errors_.

Π‘Ρ€Π°Π²Π½Π΅Π½ΠΈΠ΅

Nilai yang disimpan dalam baris ini bisa berupa apa saja. Untuk mengajar Vela untuk membandingkannya, perlu untuk mentransfer compare_by parameter dalam definisi seri (kecuali nilainya tidak dapat dibandingkan dengan standar Kernel.</2); parameter ini harus bertipe (Vela.value() -> number()). Secara default, ini sederhana & &1.

Selain itu, Anda dapat meneruskan parameter ke definisi baris comparator untuk menghitung nilai delta (min/max); misalnya dengan mentransmisikan Date.diff/2 sebagai pembanding, Anda bisa mendapatkan delta tanggal yang benar.

Cara lain yang mudah untuk bekerja adalah dengan meneruskan parameter threshold, yang menentukan rasio maksimum yang diperbolehkan dari nilai baru {min, max} selang. Karena dinyatakan sebagai persentase, cek tidak digunakan comparatortapi masih menggunakan compare_by. Misalnya, untuk menentukan nilai ambang batas waktu tanggal, Anda harus menentukannya compare_by: &DateTime.to_unix/1 (untuk mendapatkan nilai integer) dan threshold: 1, menyebabkan nilai-nilai baru diizinkan hanya jika nilai-nilai tersebut ada Β±band interval dari nilai saat ini.

Akhirnya, Anda bisa menggunakannya Vela.equal?/2 untuk membandingkan dua cache. Jika nilai mendefinisikan suatu fungsi equal?/2 ΠΈΠ»ΠΈ compare/2, maka fungsi-fungsi ini akan digunakan untuk perbandingan, jika tidak, kita akan menggunakannya dengan bodoh ==/2.

Mendapatkan nilai

Memproses status saat ini biasanya dimulai dengan panggilan Vela.purge/1, yang menghapus nilai-nilai usang (jika validator terikat pada timestamps). Anda kemudian dapat menelepon Vela.slice/1yang akan kembali keyword dengan nama baris sebagai kunci dan nilai aktual pertama.

Anda juga bisa menggunakan get_in/2/pop_in/2 untuk akses tingkat rendah ke nilai di setiap baris.

Web

Vela bisa sangat berguna sebagai cache deret waktu dalam keadaan proses seperti GenServer/Agent. Kami tidak ingin pernah menggunakan nilai kursus yang sudah usang, dan untuk melakukan hal ini kami hanya membiarkan prosesnya tetap diproses Vela, dengan validator yang ditunjukkan di bawah ini.

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

ΠΈ Vela.purge/1 diam-diam menghapus semua nilai basi setiap kali kita membutuhkan datanya. Untuk mengakses nilai sebenarnya kita cukup memanggil Vela.slice/1, dan ketika riwayat kecil kursus diperlukan (seluruh rangkaian), kami cukup mengembalikannya - sudah diurutkan - dengan nilai yang divalidasi.

Selamat menyimpan cache rangkaian waktu!

Sumber: www.habr.com

Tambah komentar