因此,假设我想每隔4个小时发送一堆电子邮件或重新创建站点地图,或者其他任何事情,我将如何在Phoenix或仅使用Elixir做到这一点?
因此,假设我想每隔4个小时发送一堆电子邮件或重新创建站点地图,或者其他任何事情,我将如何在Phoenix或仅使用Elixir做到这一点?
Answers:
有一个简单的替代方法,不需要任何外部依赖项:
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时,您可以将参数传递给task函数,如果您对UTC不满意,甚至可以修改时区。
如果您的应用程序作为多个隔离的实例(例如Heroku)运行,则有PostgreSQL或Redis支持的作业处理器,它们也支持任务调度:
奥本(Oban):https : //github.com/sorentwo/oban
例题:https://github.com/akira/exq
job = {{:weekly, :thu, {2, :am}},
{:io, :fwrite, ["It's 2 Thursday morning~n"]}}
:erlcron.cron(job)
A job
是2元素元组。第一个元素是代表作业计划的元组,第二个元素是函数或MFA(模块,函数,Arity)。在上面的示例中,我们:io.fwrite("It's 2 Thursday morning")
每星期四凌晨2点运行一次。
希望有帮助!
我使用了Quantum库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
将被调用,输出current count
,并更新GenServer的状态(count + 1
),为您提供如下输出:
1
2
3
4
[etc.]
除了使用之外Process.send_after
,您还可以使用:timer.apply_interval。