我正在尝试生成一个进程,该进程将每五秒发布一次HTTP请求,以向服务器报告其心跳。我的代码是:
defmodule MyModule.Heartbeat do
def start_link do
spawn_link(fn ->
:timer.apply_interval(:timer.seconds(5), __MODULE__, :beat, [])
end)
end
defp beat do
HTTPoison.post "https://myserver/heartbeat
end
end
defmodule MyModule.Supervisor do
use Supervisor
def start_link do
Supervisor.start_link(__MODULE__, :ok)
end
def init(:ok) do
children = [
worker(MyModule.Heartbeat, [])
]
supervise(children, strategy: :one_for_one)
end
end
然而,当我尝试启动应用程序时,它会退出并显示以下错误:
[info] Application my_module exited: MyModule.start(:normal, []) returned an error: shutdown: failed to start child: MyModule.Heartbeat
** (EXIT) #PID<0.535.0>
我需要的只是一些进程,它将作为监督树的一部分运行,并在指定的时间间隔内发送它的请求。它不需要能够自己接收任何消息,我也不会对特定的实现感到困扰。
任何人都可以建议我在这里做错了什么阻止了这个过程的启动,以及是否有更好的方法来实现这个目标?
答案 0 :(得分:1)
您的代码中有3个错误:
:timer.apply_interval/4
立即返回,因此匿名
传递给spawn_link
中MyModule.Heartbeat.start_link/0
的函数终止
执行该行后不久,导致:timer
删除间隔
它的队列,而不是永远调用MyModule.Heartbeat.beat/0
。
您可以通过添加:timer.sleep(:infinity)
作为最后一个来解决此问题
表达式,使你的过程永远睡眠。
MyModule.Heartbeat.beat/0
需要是一个公共函数才能成为
传递给spawn_link
的匿名函数可以调用它。
MyModule.Heartbeat.start_link/0
成功时需要返回{:ok, pid}
。
spawn_link
只返回一个pid。
这3次更改后的最终代码:
defmodule MyModule.Heartbeat do
def start_link do
pid = spawn_link(fn ->
:timer.apply_interval(:timer.seconds(5), __MODULE__, :beat, [])
:timer.sleep(:infinity)
end)
{:ok, pid}
end
def beat do
IO.puts "beat"
end
end
defmodule MyModule.Supervisor do
use Supervisor
def start_link do
Supervisor.start_link(__MODULE__, :ok)
end
def init(:ok) do
children = [
worker(MyModule.Heartbeat, [])
]
supervise(children, strategy: :one_for_one)
end
end
输出:
iex(1)> MyModule.Supervisor.start_link
{:ok, #PID<0.84.0>}
iex(2)> beat
beat
beat
beat
我不确定你是否甚至需要所有这些设置作为该函数引发的异常
传递给:timer.apply_interval
不会影响调用过程。该
以下脚本一直试图运行该函数,即使它总是引发一个
例外:
defmodule Beat do
def beat do
raise "hey"
end
end
:timer.apply_interval(:timer.seconds(1), Beat, :beat, [])
:timer.sleep(:infinity)
输出:
$ elixir a.exs
16:00:43.207 [error] Process #PID<0.53.0> raised an exception
** (RuntimeError) hey
a.exs:3: Beat.beat/0
16:00:44.193 [error] Process #PID<0.54.0> raised an exception
** (RuntimeError) hey
a.exs:3: Beat.beat/0
16:00:45.193 [error] Process #PID<0.55.0> raised an exception
** (RuntimeError) hey
a.exs:3: Beat.beat/0