Quindi diciamo che voglio inviare un sacco di e-mail o ricreare una sitemap o qualsiasi altra ogni 4 ore, come potrei farlo a Phoenix o semplicemente con Elisir?
Quindi diciamo che voglio inviare un sacco di e-mail o ricreare una sitemap o qualsiasi altra ogni 4 ore, come potrei farlo a Phoenix o semplicemente con Elisir?
Risposte:
Esiste una semplice alternativa che non richiede dipendenze esterne:
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
Ora nel tuo albero di supervisione:
worker(MyApp.Periodically, [])
Process.send_after
nella propria funzione in modo che la funzione possa essere chiamata da entrambi init
e handle_info
?
:timer.send_interval
va bene, ma tieni presente che gli intervalli saranno costanti. Quindi immagina di voler fare qualcosa ogni minuto e, in futuro, il lavoro stesso richiede più di un minuto. In questi casi, lavoreresti continuamente e la coda dei messaggi aumenterebbe senza limiti. La soluzione sopra attenderà sempre il periodo indicato dopo il completamento del lavoro.
quantistico consente di creare, trovare ed eliminare lavori in fase di esecuzione.
Inoltre, puoi passare argomenti alla funzione task durante la creazione di un cronjob e persino modificare il fuso orario se non sei soddisfatto di UTC.
Se la tua app viene eseguita come istanze multiple isolate (ad es. Heroku), ci sono processori supportati da PostgreSQL o Redis, che supportano anche la pianificazione delle attività:
Oban: https://github.com/sorentwo/oban
Exq: https://github.com/akira/exq
Puoi usare erlcron per questo. Lo usi come
job = {{:weekly, :thu, {2, :am}},
{:io, :fwrite, ["It's 2 Thursday morning~n"]}}
:erlcron.cron(job)
A job
è una tupla a 2 elementi. Il primo elemento è una tupla che rappresenta la pianificazione per il lavoro e il secondo elemento è la funzione o un MFA (Modulo, Funzione, Arità). Nell'esempio sopra, eseguiamo :io.fwrite("It's 2 Thursday morning")
ogni 2:00 di giovedì.
Spero che aiuti!
Ho usato la libreria Quantum Quantum -Elixir .
Seguire le istruzioni seguenti.
#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
]
Tutto stabilito. Avviare il server eseguendo il comando seguente.
iex -S mix phoenix.server
Trovo :timer.send_interval/2
un po 'più ergonomico da usare con un GenServer
rispetto Process.send_after/4
(usato nella risposta accettata ).
Invece di dover riprogrammare la tua notifica ogni volta che la gestisci, :timer.send_interval/2
imposta un intervallo in cui ricevi un messaggio all'infinito, non è necessario continuare a chiamare schedule_work()
come usa la risposta accettata.
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
Ogni 1000 ms (ovvero, una volta al secondo), IntervalServer.handle_info/2
verrà chiamato, stampa la corrente count
e aggiorna lo stato del GenServer ( count + 1
), dandoti un output come:
1
2
3
4
[etc.]
Oltre a usare Process.send_after
, puoi anche usare : timer.apply_interval .
Quantum è fantastico, lo usiamo sul posto di lavoro come sostituto del cron con un front-end di Phoenix e aggiungiamo anche lavori in tempo reale che è molto pulito.