2016-09-08 12 views
2

그래서 루프에서 실행되고 특정 작업을 수행하는 엘릭시어 프로그램이 있습니다. 나는 하나의 사육사 연결 인스턴스를 생성하고 루프에서 동일한 인스턴스를 사용하도록 에이전트를 선언했습니다. 내 코드는 다음과 같은 : -엘렉서의 루프에서 에이전트가 반환 한 값을 사용할 수 없습니다.

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를 출력하면 항상 같은 결과를 얻습니다. 즉, 동일한 인스턴스가 항상 반환됩니다. 그러나 나는 다음과 같은 오류가 점점 오전 : -

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 : - 그것을 재현하려면 내가 잘못 생성 된 프로세스에 대한 루프를 실행 한 것으로 보인다 사육사 설정

+0

'get_zk/0'에서'zk'를 반환하겠습니까? '{: ok, zk} = ZK.start (@zk_quorams)'->'{: ok, zk} = ZK.start (@zk_quorams); zk'? 그래도 문제가 해결되지 않으면 [MCVE] (http://stackoverflow.com/help/mcve)를 게시 할 수 있습니까? – Dogbert

+0

get_zk/0에'zk'를 돌려 주어 해결할 수 없습니다. 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