我试图同时监控多个API。目前我正在启动我的应用程序,然后启动我的主管,然后启动监控过程。我虚弱的大脑已经设法达到我产生所有4个子进程的程度。
我的APIMon.Monitor
模块很乱,我不确定如何修复它。我想要的是每个人都作为主管的孩子开始,然后无限期地在他们自己的scan()
循环中运行,同时所有信息都独立地输出到控制台。
我已经玩了一段时间并试图通过任务文档,我似乎无法找到一种方法让这项工作完全阻止我的控制台在iex -S mix
中,我认为这意味着我完全阻止了。我希望能够在这些任务正在运行或休眠时在控制台中执行命令。
非常感谢任何帮助。
defmodule APIMon do
@API [
%{id: "A", host: '192.168.1.5', port: 3001},
%{id: "B", host: '192.168.1.7', port: 3001},
%{id: "C", host: '192.168.1.8', port: 3001},
%{id: "D", host: '192.168.1.9', port: 3001}
]
def start(_type, _args) do
APIMon.Supervisor.start_link(@API)
end
end
defmodule APIMon.Supervisor do
use Supervisor
def start_link(args) do
Supervisor.start_link(__MODULE__, args, name: __MODULE__)
end
def init(args) do
children =
args
|> Enum.reduce([], fn child, acc ->
acc =
acc ++ [Supervisor.child_spec({APIMon.Monitor, child}, id: "Worker_#{child.id}")]
end)
Supervisor.init(children, strategy: :one_for_one)
end
end
defmodule APIMon.Monitor do
use GenServer
def start_link(arg) do
id = arg.id
GenServer.start_link(__MODULE__, arg, name: :"#{__MODULE__} [#{id}]")
end
## Callbacks
def init(arg) do
pid = Kernel.inspect(self())
IO.puts "Adding API monitor #{arg.id} to the stack as #{pid}"
scan()
{:ok, arg}
end
def scan() do
task = Task.async(fn ->
#do individual API health checks here
end)
Task.await(task)
:timer.sleep(2500)
scan()
end
end
答案 0 :(得分:4)
APIMon.Monitor
的问题是它无法从init
返回 - 您正在进入无限循环调用scan()
。你可以通过向本身发送消息来解决这个问题。
听起来有点神秘,所以让我给你举个例子:
defmodule APIMon.Monitor do
use GenServer
def start_link(arg) do
id = arg.id
GenServer.start_link(__MODULE__, arg, name: :"#{__MODULE__} [#{id}]")
end
## Callbacks
def init(arg) do
pid = Kernel.inspect(self())
IO.puts "Adding API monitor #{arg.id} to the stack as #{pid}"
Process.send_after(self(), :scan, 2500)
{:ok, arg}
end
def handle_info(:scan, state) do
#do individual API health checks here
Process.send_after(self(), :scan, 2500)
{:noreply, state}
end
end
除此之外,我不认为你的代码是一团糟 - 这是一个结构良好的Elixir / OTP代码!
希望有所帮助!