2017-12-30 33 views
0

GenServer을 아래와 같이 사용하고 있습니다. init 메소드에서 데이터베이스에 대한 redis 연결을 작성합니다. put 메서드는 redisdb에 저장할 값을 전송합니다. handle_cast 메서드는 redis connection 명령을 호출하여 데이터베이스 작업을 수행합니다.내 GenServer handle_cast가 호출되지 않는 이유는 무엇입니까

defmodule RedisClient do 
    use GenServer 
    require Logger 

    # Client 
    def start(url, pwd, hkey) do 
    GenServer.start(__MODULE__, {url, pwd, hkey}); 
    end 

    def init({url, pwd, hkey}) do 
    Logger.info("connect to url #{url} #{pwd} #{hkey}"); 
    case Redix.start_link(url) do 
     {:ok, conn} -> case Redix.command(conn, ["auth", pwd]) do 
     {:ok, message} -> {:ok, conn, hkey} 
     _ -> {:error} 
     end 
    end 
    end 

    def put(pid, field, value) do 
    Logger.info("put #{field} #{value}") 
    GenServer.cast(pid, {:hset, field, value}) 
    end 

    def handle_cast({:hset, field, value}, {conn, hkey}) do 
    Logger.info("write to database #{field} #{value}") 
    result = Redix.command(conn, ["hset", hkey, field, value]); 
    {:noreply, {conn, hkey}} 
    end 

end 

다음은 iex 콘솔의 출력입니다. 데이터베이스 연결이 설정되었지만 put 메서드를 호출하면 handle_cast이 호출되지 않습니다. 내 구현에 어떤 문제가 있습니까?

iex([email protected])85> {:ok, pid} = RedisClient.start("redis://localhost", "mypassword", "mykey") 
{:ok, #PID<0.23038.0>} 
iex([email protected])86> 
11:19:49.554 [info] connect to url redis://localhost mypassword mykey 
iex([email protected])87> RedisClient.put(pid, "field1", "value1") 
:ok 
iex([email protected])88> 
11:20:26.429 [info] put field1 value1 
+0

init/1에서'{ok, {conn, hkey}}'를 돌려줘야한다고 생각합니다. – Dogbert

+0

'start_link'를 사용하여 시작하십시오 - 당신이하고있는 일을 안다면'start' 만 사용하십시오, 기본적으로 당신은 링크 된 프로세스를 원합니다. 질문을 완전히받지 못했습니다. REPL 세션에서 올바른 동작을 보여줍니다. 뭐가 잘못 되었 니? – cdegroot

+0

'start_link'와'start'의 차이점은 무엇입니까? 문제는'handle_cast'가 호출되지 않고 @Justin_Wood가 그에 대한 정답을 주었다는 것입니다. –

답변

0

GenServer이 실제로 실행되지 않습니다. 다음 코드를 실행하면 동일한 결과가 나타납니다.

iex(1)> {:ok, pid} = RedisClient.start(url, pwd, hkey) 
iex(2)> Process.alive?(pid) 
false 

문제

는 당신이 당신의 GenServerinit/1 콜백에서 세 가지 요소 튜플을 반환하는 것입니다. 세 번째 옵션은 제한 시간입니다. hkey에 유효한 시간 초과 값이 없기 때문에 GenServer이 시작되면 충돌이 발생합니다.

귀하의 경우에는 대신 {:ok, {conn, hkey}}을 보내주십시오.