2016-09-08 9 views
2

Итак, у меня есть программа elixir, которая работает в цикле и выполняет определенные операции. Я объявил, что Агент создал один экземпляр соединения zookeeper, а затем использовал его в цикле. Ниже мой код: -Невозможно использовать значение, возвращаемое агентом в цикле в elixir

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 

Теперь, если я печатаю pid zk, я всегда получаю то же самое, что означает, что всегда возвращается тот же самый экземпляр 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>} 

Кроме того, если я всегда инициализировать гк в цикле вместо ссылки от агента, мой код работает отлично.

PS: - Для того, чтобы воспроизвести его нужно иметь установку Zookeeper

+0

Вы имели в виду 'zk' в' get_zk/0'? '{: ok, zk} = ZK.start (@zk_quorams)' -> '{: ok, zk} = ZK.start (@zk_quorams); zk'? Если это не исправить, не могли бы вы отправить сообщение [MCVE] (http://stackoverflow.com/help/mcve)? – Dogbert

+0

Невозможно решить, возвращая 'zk' в get_zk/0. Выложили MCVE. –

+0

Попробуйте также изменить 'ZK.get_children (zk,"/test ")' на 'ZK.get_children (Agent.get (zk, & (& 1)),"/test ")'. – Dogbert

ответ

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