Vela β†’ cache pintar untuk siri masa dan banyak lagi

Dalam fintech, kita selalunya perlu memproses jumlah data kadar pertukaran mata wang yang agak besar. Kami mendapat data daripada sumber yang berbeza, dan setiap daripada mereka mempunyai idea sendiri tentang cara mengekstrapolasi kadar pertukaran untuk esok, lusa, bulan depan dan juga tiga tahun akan datang. Sekiranya seseorang boleh meramalkan kadar betul, sudah tiba masanya untuk menutup perniagaan dan menukar wang secara bodoh ke sana ke mari. Sesetengah sumber lebih dipercayai, ada yang membekalkan sampah lengkap, dengan kemasukan jarang nilai yang hampir betul, tetapi untuk pasangan eksotik. Tugas kami adalah untuk menapis berpuluh-puluh ribu nilai sesaat ini dan menentukan apa sebenarnya yang perlu ditunjukkan kepada pelanggan. Kita perlu menapis satu nilai yang betul daripada banyak kotoran dan kelodak, seperti yang dilakukan oleh flamingo semasa makan tengah hari.

Vela β†’ cache pintar untuk siri masa dan banyak lagi

Ciri khas yang membezakan flamingo ialah paruhnya yang besar melengkung ke bawah, yang dengannya mereka menapis makanan daripada air atau lumpur.
 - Wiki

Maka lahirlah perpustakaan Vela, yang menyimpan cache keadaan untuk berbilang nilai pada selang masa tertentu. Di bawah hud, ia menapis data yang buruk dan lapuk dengan cepat, dan juga menyediakan akses kepada yang terkini N nilai yang disahkan untuk setiap kunci (pasangan mata wang, dalam kes kami).

Katakan kami mengumpul kadar untuk tiga pasangan mata wang. Definisi paling mudah Vela untuk menyimpan keadaan semasa ia akan kelihatan 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

Mengemas kini Nilai

Vela.put/3 Fungsi akan melakukan perkara berikut dalam urutan:

  • akan menyebabkan validator pada nilai, jika satu ditakrifkan (lihat bab Pengesahan di bawah);
  • akan menambah nilai sama ada pada baris nilai baik jika pengesahan berjaya, atau pada baris perkhidmatan :__errors__ sebaliknya;
  • akan menyebabkan pengisihan jika sorter ditakrifkan untuk kunci yang diberikan, atau hanya akan meletakkan nilai di kepala senarai (LIFO, lihat bab Π‘ΠΎΡ€Ρ‚ΠΈΡ€ΠΎΠ²ΠΊΠ° di bawah);
  • akan memangkas baris mengikut parameter :limit diturunkan kepada penciptaan;
  • akan mengembalikan struktur yang dikemas kini 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 melaksanakan Access, jadi anda boleh menggunakan mana-mana fungsi standard untuk mengemas kini struktur mendalam daripada senjata untuk mengemas kini 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.

Pengesahan

Pengesah boleh ditakrifkan sebagai:

  • fungsi luaran dengan satu hujah (&MyMod.my_fun/1), ia hanya akan menerima nilai untuk pengesahan;
  • fungsi luaran dengan dua hujah, &MyMod.my_fun/2, dia akan dapat sepasang serie, value untuk pengesahan;
  • pelaksanaan modul Vela.Validator;
  • parameter konfigurasi threshold, dan - pilihan - compare_by, lihat bab perbandingan di bawah.

Jika pengesahan berjaya, nilai ditambah pada senarai di bawah kunci yang sepadan; jika tidak, tuple {serie, value} dihantar ke :__errors_.

Perbandingan

Nilai yang disimpan dalam baris ini boleh menjadi apa sahaja. Untuk mengajar Vela untuk membandingkan mereka, adalah perlu untuk memindahkan compare_by parameter dalam definisi siri (melainkan nilai tidak boleh dibandingkan dengan standard Kernel.</2); parameter ini mestilah jenis (Vela.value() -> number()). Secara lalai ia mudah & &1.

Juga, anda boleh menghantar parameter kepada definisi baris comparator untuk mengira nilai delta (min/max); contohnya, dengan menghantar Date.diff/2 sebagai pembanding, anda boleh mendapatkan delta yang betul untuk tarikh.

Satu lagi cara yang mudah untuk berfungsi ialah dengan lulus parameter threshold, yang mentakrifkan nisbah maksimum yang dibenarkan bagi nilai baharu kepada {min, max} selang waktu. Oleh kerana ia dinyatakan sebagai peratusan, cek tidak digunakan comparatortapi masih guna compare_by. Sebagai contoh, untuk menentukan nilai ambang untuk masa tarikh, anda mesti menentukan compare_by: &DateTime.to_unix/1 (untuk mendapatkan nilai integer) dan threshold: 1, menyebabkan nilai baharu dibenarkan hanya jika ia berada dalam Β±band selang daripada nilai semasa.

Akhirnya, anda boleh menggunakan Vela.equal?/2 untuk membandingkan dua cache. Jika nilai mentakrifkan fungsi equal?/2 atau compare/2, maka fungsi-fungsi ini akan digunakan untuk perbandingan, jika tidak, kita menggunakan secara bodoh ==/2.

Mendapat nilai

Memproses keadaan semasa biasanya bermula dengan panggilan Vela.purge/1, yang mengalih keluar nilai usang (jika validator terikat kepada timestamps). Anda kemudian boleh menghubungi Vela.slice/1yang akan kembali keyword dengan nama baris sebagai kunci dan yang pertama, nilai sebenar.

Anda juga boleh menggunakan get_in/2/pop_in/2 untuk akses peringkat rendah kepada nilai dalam setiap baris.

Permohonan

Vela boleh menjadi sangat berguna sebagai cache siri masa dalam keadaan proses seperti GenServer/Agent. Kami tidak mahu sekali-kali menggunakan nilai kursus yang lapuk, dan untuk melakukan ini, kami hanya menyimpan proses dengan keadaan diproses Vela, dengan pengesah ditunjukkan di bawah.

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

ΠΈ Vela.purge/1 secara senyap-senyap membuang semua nilai lapuk setiap kali kami memerlukan data. Untuk mengakses nilai sebenar kami hanya memanggil Vela.slice/1, dan apabila sejarah kecil kursus diperlukan (keseluruhan siri), kami hanya mengembalikannyaβ€”sudah diisihβ€”dengan nilai yang disahkan.

Selamat melakukan cache siri masa!

Sumber: www.habr.com

Tambah komen