Jadi katakanlah saya ingin mengirim banyak email atau membuat ulang sitemap atau apa pun setiap 4 jam, bagaimana saya melakukannya di Phoenix atau hanya dengan Elixir?
Jadi katakanlah saya ingin mengirim banyak email atau membuat ulang sitemap atau apa pun setiap 4 jam, bagaimana saya melakukannya di Phoenix atau hanya dengan Elixir?
Jawaban:
Ada alternatif sederhana yang tidak memerlukan ketergantungan eksternal:
defmodule MyApp.Periodically do
use GenServer
def start_link do
GenServer.start_link(__MODULE__, %{})
end
def init(state) do
schedule_work() # Schedule work to be performed at some point
{:ok, state}
end
def handle_info(:work, state) do
# Do the work you desire here
schedule_work() # Reschedule once more
{:noreply, state}
end
defp schedule_work() do
Process.send_after(self(), :work, 2 * 60 * 60 * 1000) # In 2 hours
end
end
Sekarang di pohon pengawasan Anda:
worker(MyApp.Periodically, [])
Process.send_after
ke fungsinya sendiri sehingga fungsinya dapat dipanggil dari keduanya init
dan handle_info
?
:timer.send_interval
baik-baik saja tetapi perlu diingat bahwa interval akan konstan. Jadi bayangkan Anda ingin melakukan sesuatu setiap menit dan, di masa depan, pekerjaan itu sendiri membutuhkan lebih dari satu menit. Dalam kasus seperti itu, Anda akan bekerja sepanjang waktu dan antrian pesan Anda akan menjadi tidak terbatas. Solusi di atas akan selalu menunggu periode yang diberikan setelah pekerjaan selesai.
Quantum memungkinkan Anda membuat, menemukan, dan menghapus pekerjaan saat runtime.
Selain itu, Anda dapat meneruskan argumen ke fungsi tugas saat membuat tugas cronjob, dan bahkan memodifikasi zona waktu jika Anda tidak puas dengan UTC.
Jika aplikasi Anda berjalan sebagai beberapa instance yang terisolasi (mis. Heroku), ada pemroses pekerjaan yang didukung oleh PostgreSQL atau Redis, yang juga mendukung penjadwalan tugas:
Oban: https://github.com/sorentwo/oban
Exq: https://github.com/akira/exq
Anda dapat menggunakan erlcron untuk itu. Anda menggunakannya seperti
job = {{:weekly, :thu, {2, :am}},
{:io, :fwrite, ["It's 2 Thursday morning~n"]}}
:erlcron.cron(job)
A job
adalah tuple 2 elemen. Elemen pertama adalah tupel yang mewakili jadwal untuk pekerjaan dan elemen kedua adalah fungsi atau MFA (Modul, Fungsi, Arity). Dalam contoh di atas, kita jalankan:io.fwrite("It's 2 Thursday morning")
setiap 2 Kamis.
Semoga itu bisa membantu!
Saya menggunakan perpustakaan Quantum Quantum- Elixir .
Ikuti instruksi di bawah ini.
#your_app/mix.exs
defp deps do
[{:quantum, ">= 1.9.1"},
#rest code
end
#your_app/mix.exs
def application do
[mod: {AppName, []},
applications: [:quantum,
#rest code
]]
end
#your_app/config/dev.exs
config :quantum, :your_app, cron: [
# Every minute
"* * * * *": fn -> IO.puts("Hello QUANTUM!") end
]
Siap. Mulai server dengan menjalankan perintah di bawah ini.
iex -S mix phoenix.server
Saya menemukan :timer.send_interval/2
sedikit lebih ergonomis untuk digunakan dengan GenServer
dari Process.send_after/4
(digunakan dalam jawaban yang diterima ).
Alih-alih harus menjadwal ulang notifikasi Anda setiap kali Anda menanganinya, :timer.send_interval/2
tentukan interval di mana Anda menerima pesan tanpa henti — tidak perlu terus menelepon schedule_work()
seperti yang digunakan jawaban yang diterima.
defmodule CountingServer do
use GenServer
def init(_) do
:timer.send_interval(1000, :update)
{:ok, 1}
end
def handle_info(:update, count) do
IO.puts(count)
{:noreply, count + 1}
end
end
Setiap 1000 ms (yaitu, satu detik), IntervalServer.handle_info/2
akan dipanggil, cetak saat ini count
, dan perbarui status GenServer ( count + 1
), memberikan Anda output seperti:
1
2
3
4
[etc.]
Selain untuk digunakan Process.send_after
, Anda juga dapat menggunakan : timer.apply_interval .