Тож скажімо, що я хочу надсилати купу електронних листів або відтворювати мапу сайту чи будь-які інші кожні 4 години, як би це зробити у Phoenix чи просто з Elixir?
Тож скажімо, що я хочу надсилати купу електронних листів або відтворювати мапу сайту чи будь-які інші кожні 4 години, як би це зробити у Phoenix чи просто з Elixir?
Відповіді:
Існує проста альтернатива, яка не потребує зовнішніх залежностей:
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
Тепер у вашому дереві спостереження:
worker(MyApp.Periodically, [])
Process.send_after
до власної функції, щоб функцію можна було викликати і з init
і handle_info
?
:timer.send_interval
чудово, але майте на увазі, що інтервали будуть постійними. Тож уявіть, що хочете щось робити щохвилини, і в майбутньому сама робота займає більше хвилини. У таких випадках ви будете працювати весь час, і ваша черга повідомлень зростатиме без обмежень. Наведене вище рішення завжди буде чекати заданого періоду після закінчення роботи.
Quantum дозволяє створювати, знаходити та видаляти завдання під час виконання.
Крім того, ви можете передавати аргументи функції завдання під час створення cronjob і навіть змінювати часовий пояс, якщо вас не влаштовує UTC.
Якщо ваш додаток працює як кілька ізольованих екземплярів (наприклад, Heroku), є процесори завдань, підтримувані PostgreSQL або Redis, які також підтримують планування завдань:
Обан: https://github.com/sorentwo/oban
Exq: https://github.com/akira/exq
Ви можете використовувати erlcron для цього. Ви використовуєте це як
job = {{:weekly, :thu, {2, :am}},
{:io, :fwrite, ["It's 2 Thursday morning~n"]}}
:erlcron.cron(job)
A job
- двоярусний кортеж. Перший елемент - кортеж, який представляє графік роботи, а другий елемент - це функція або MFA (модуль, функція, Arity). У наведеному прикладі ми проводимо :io.fwrite("It's 2 Thursday morning")
кожні 2 години ночі четверга.
Сподіваюся, що це допомагає!
Я використовував квантову бібліотеку Quantum- Elixir .
Дотримуйтесь інструкцій нижче.
#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
]
Все готово. Запустіть сервер, виконавши команду нижче.
iex -S mix phoenix.server
Я вважаю :timer.send_interval/2
трохи більш ергономічним для використання з ( GenServer
ніж Process.send_after/4
використовується у прийнятій відповіді ).
Замість того, щоб переносити своє повідомлення щоразу, коли ви його обробляєте, :timer.send_interval/2
встановлюйте інтервал, протягом якого ви отримуєте повідомлення нескінченно - не потрібно продовжувати дзвінки, schedule_work()
як використовується прийнята відповідь.
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
Кожні 1000 мс (тобто раз на секунду) IntervalServer.handle_info/2
буде викликано, надрукується поточний count
та оновиться стан GenServer ( count + 1
), даючи вихід, як:
1
2
3
4
[etc.]
Крім використання Process.send_after
, ви можете також використовувати : timer.apply_interval .
Квант чудовий, ми використовуємо його на роботі як заміну крона фенікс-фронтом, а також додаємо завдання в реальному часі, що дуже акуратно.