所以我有一个elixir程序,它在一个循环中运行并执行某些操作。我已经声明了一个Agent来创建一个zookeeper连接实例,然后在循环中使用它。以下是我的代码: -
mix.exs
def application do
[
applications: [:logger, :zookeeper],
mod: {ServiceMonitor, []}
]
end
defp deps do
[
{:zookeeper, github: "vishnevskiy/zookeeper-elixir"}
]
end
service_monitor.ex
defmodule ServiceMonitor do
def start(_type, _args) do
{:ok, zk_agent} = Agent.start_link(fn -> ServiceMonitor.Registry.get_zk end)
ServiceMonitor.Registry.start_process(zk_agent)
end
end
service_monitor / registry.ex
defmodule ServiceMonitor.Registry do
alias Zookeeper.Client, as: ZK
def start_process(zk) do
pid = spawn_link(fn ->
{:ok, data} = ZK.get_children(zk, "/test")
IO.inspect(data)
end)
start_process(zk)
end
def get_zk do
{:ok, zk} = ZK.start("localhost:2181")
zk
end
end
现在,如果我打印zk的pid,我总是得到相同的,这意味着始终返回相同的zk实例。但我收到以下错误: -
12:44:39.647 [error] GenServer #PID<0.165.0> terminating
** (stop) bad call: #Operation performed by zk
(elixir) lib/gen_server.ex:420: Agent.Server."handle_call (overridable 1)"/3
(stdlib) gen_server.erl:629: :gen_server.try_handle_call/4
(stdlib) gen_server.erl:661: :gen_server.handle_msg/5
(stdlib) proc_lib.erl:240: :proc_lib.init_p_do_apply/3
Last message: #
State: {:ok, #PID<0.166.0>}
另外,如果我总是在循环中初始化zk而不是从代理引用,我的代码工作正常。
PS: - 要重现它,你需要设置一个zookeeper
答案 0 :(得分:0)
似乎我错误地为生成的进程运行循环。 Dogbert关于如何在循环中获取代理返回的值的解决方案实际上有效。现在,我在生成的进程上运行循环,如下所示: -
def start_process(zk_agent) do
spawn(ServiceMonitor.Registry, :start,[zk_agent])
:timer.sleep(@sleep_time)
start_process(zk_agent)
end
def start_process(zk_agent) do
zk = Agent.get(zk_agent, &(&1))
#Other logics
end