How can I schedule code to run every few hours in

2020-01-26 12:47发布

So let's say I want to send a bunch of emails or recreate sitemap or whatever every 4 hours, how would I do that in Phoenix or just with Elixir?

7条回答
ゆ 、 Hurt°
2楼-- · 2020-01-26 12:47

I used Quantum library Quantum- Elixir.
Follow below instructions.

#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
]

All set. Start the server by running below command.

iex -S mix phoenix.server 
查看更多
混吃等死
3楼-- · 2020-01-26 12:51

There is a simple alternative that does not require any external dependencies:

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

Now in your supervision tree:

worker(MyApp.Periodically, [])
查看更多
趁早两清
4楼-- · 2020-01-26 13:00

You can use erlcron for that. You use it like

job = {{:weekly, :thu, {2, :am}},
  {:io, :fwrite, ["It's 2 Thursday morning~n"]}}

:erlcron.cron(job)

A job is a 2-element tuple. The first element is a tuple that represents the schedule for the job and the second element is the function or an MFA(Module, Function, Arity). In the above example, we run :io.fwrite("It's 2 Thursday morning") every 2am of Thursday.

Hope that helps!

查看更多
叼着烟拽天下
5楼-- · 2020-01-26 13:00

Besides to use Process.send_after, you can also use :timer.apply_interval.

查看更多
Lonely孤独者°
6楼-- · 2020-01-26 13:08

I find :timer.send_interval/2 slightly more ergonomic to use with a GenServer than Process.send_after/4 (used in the accepted answer).

Instead of having to reschedule your notification each time you handle it, :timer.send_interval/2 sets up an interval on which you receive a message endlessly—no need to keep calling schedule_work() like the accepted answer uses.

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

Every 1000 ms (i.e., once a second), IntervalServer.handle_info/2 will be called, print the current count, and update the GenServer's state (count + 1), giving you output like:

1
2
3
4
[etc.]
查看更多
Summer. ? 凉城
7楼-- · 2020-01-26 13:09

Quantum is great, we use it at work as a cron replacement with a phoenix front-end and we also add jobs in real-time which is very neat.

查看更多
登录 后发表回答