【发布时间】:2019-02-23 17:03:49
【问题描述】:
我正在我的台式计算机 (Mac OS) 上开发一个应用程序,为此我创建了一些每 5 分钟运行一次的 cron 任务。代码如下(取自here):
defmodule MyApp.CronJobs do
use GenServer
@shops ["billa","kaufland","lidl"]
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
Enum.each(@shops, &monitor_prices/1)
schedule_work() # Reschedule once more
{:noreply, state}
end
defp monitor_price(shop)
Mix.Task.run "monitor.#{shop}.all_prices"
end
defp schedule_work() do
Process.send_after(self(), :work, 5 * 60 * 1000)
end
end
在监督树上:
...
children = [
supervisor(MyApp.CronJobs, [])
...
]
opts = [ strategy: :one_for_one, name: MyApp.Supervisor]
Supervisor.start_link(children, opts)
问题在于它与服务器一起运行,因此只要计算机进入睡眠模式,它就会停止运行。
有没有办法让进程在后台永久运行,而无需让计算机一直处于全功率模式?更好的是,有没有办法在不运行服务器的情况下每 5 分钟触发一次混合任务?
【问题讨论】:
-
睡眠有点类似于关闭计算机,并且无法在睡眠模式下运行任何进程,因为所有进程都已暂停,因此如果要保持任务运行,则必须禁用睡眠模式并始终保持开启状态。或者在某处部署您的应用程序。为什么你需要在开发模式下运行所有这些任务?顺便说一句,你这里根本没有使用 cron,这是 BEAM 的内部进程调度
-
我知道这不是真正的 cron 工作,但他们管理相同的 @BogdanAgafonov 。理想情况下,我想在某个时间间隔触发混合任务,而无需运行服务器,但我不知道如何在 elixir 应用程序中实现这一点。
-
您想将某些东西作为“守护进程”运行。最简单的方法可能是将您的代码转换为混合任务并使用 CRON,但您也可以查看 distillery 版本 + sysctl 或其他守护程序。您也可以直接使用 sysctl 和 iex 在后台运行它。
标签: elixir phoenix-framework cron-task elixir-mix