Diyelim ki bir grup e-posta göndermek veya site haritasını yeniden oluşturmak istiyorum ya da her 4 saatte bir, bunu Phoenix'te veya sadece Elixir ile nasıl yapabilirim?
Diyelim ki bir grup e-posta göndermek veya site haritasını yeniden oluşturmak istiyorum ya da her 4 saatte bir, bunu Phoenix'te veya sadece Elixir ile nasıl yapabilirim?
Yanıtlar:
Herhangi bir dış bağımlılık gerektirmeyen basit bir alternatif var:
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
Şimdi denetim ağacında:
worker(MyApp.Periodically, [])
Process.send_after
iki işlevden de çağrılabilmesi için kendi işlevine geçmemek için herhangi bir özel neden init
ve handle_info
?
:timer.send_interval
iyidir, ancak aralıkların sabit olacağını unutmayın. Her dakika bir şeyler yapmak istediğinizi düşünün ve gelecekte işin kendisi bir dakikadan fazla sürüyor. Bu gibi durumlarda her zaman çalışırsınız ve mesaj kuyruğunuz sınırsız büyür. Yukarıdaki çözüm her zaman iş bittikten sonra belirtilen süreyi bekleyecektir .
Quantum , çalışma zamanında iş oluşturmanıza, bulmanıza ve silmenize olanak tanır.
Ayrıca, bir cronjob oluştururken görev işlevine bağımsız değişkenler iletebilir ve hatta UTC'den memnun değilseniz saat dilimini değiştirebilirsiniz.
Uygulamanız birden çok yalıtılmış örnek olarak çalışıyorsa (örn. Heroku), görev zamanlamasını da destekleyen PostgreSQL veya Redis tarafından desteklenen iş işlemcileri vardır:
Oban: https://github.com/sorentwo/oban
Örnek: https://github.com/akira/exq
Bunun için erlcron kullanabilirsiniz . Gibi kullanıyorsun
job = {{:weekly, :thu, {2, :am}},
{:io, :fwrite, ["It's 2 Thursday morning~n"]}}
:erlcron.cron(job)
A job
, 2 elemanlı bir demettir. İlk öğe, işin zamanlamasını temsil eden bir demettir ve ikinci öğe işlev veya bir MFA'dır (Modül, İşlev, Arity). Yukarıdaki örnekte, :io.fwrite("It's 2 Thursday morning")
Perşembe gününün her 2 am'ını çalıştırıyoruz .
Umarım yardımcı olur!
Quantum kütüphanesi Quantum- Elixir kullandım .
Aşağıdaki talimatları izleyin.
#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
]
Her şey hazır. Aşağıdaki komutu çalıştırarak sunucuyu başlatın.
iex -S mix phoenix.server
Ben bulmak :timer.send_interval/2
bir ile kullanmak biraz daha ergonomik GenServer
daha Process.send_after/4
(kullanılan kabul edilen cevap ).
Bildiriminizi her kullandığınızda yeniden planlamak zorunda kalmak yerine, :timer.send_interval/2
sonsuz bir ileti aldığınız bir aralık belirler schedule_work()
; kabul edilen yanıtın kullandığı gibi aramaya devam etmenize gerek yoktur .
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
Her 1000 ms'de (yani saniyede bir kez) IntervalServer.handle_info/2
çağrılacak, akımı yazdıracak count
ve GenServer'ın durumunu ( count + 1
) güncelleyeceksiniz.
1
2
3
4
[etc.]
Kullanmanın yanı sıra Process.send_after
şunları da kullanabilirsiniz : timer.apply_interval .
Kuantum harika, anka kuşu ön uçlu bir cron replasmanı olarak işte kullanıyoruz ve ayrıca gerçek zamanlı olarak çok temiz olan işler ekliyoruz .