2017-12-30 8 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コールバックから3つの要素のタプルを返しているということです。 3番目のオプションはタイムアウトになっています。 hkeyが有効なタイムアウト値を保持していないため、起動時にGenServerがクラッシュしています。

あなたの場合、代わりに{:ok, {conn, hkey}}を返すことをお勧めします。

関連する問題