在不运行phx.server的情况下无法运行cron任务

时间:2018-09-19 13:38:54

标签: elixir phoenix-framework cron-task mix

我正在台式计算机(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分钟触发一次而无需运行服务器?

1 个答案:

答案 0 :(得分:0)

您可以使用计划的唤醒和睡眠对OSX进行编程,这样可以解决您的睡眠问题。您还可以协调“真实”的cron作业,以在同一窗口中运行脚本。

混合任务的问题在于它们通常从项目的根文件夹运行,因为它们需要运行项目的上下文。这并不是真正的“生产”解决方案。您安装了可从任何目录运行的存档,但是有更好的方法。

看看手稿。您为混合项目构建了脚本,然后将其安装在系统上。然后,您可以从计划的cron作业中运行脚本。

我怀疑您的解决方案中将需要GenServer,因为上面的示例未使用任何持久状态。如果需要并发,则可以简单地生成一些进程或使用Task运行一些并发代码。

根据您完整解决方案的复杂性,您可能希望查看Distillery来为您的项目打包发行版,但这可能会显得过分。