2016-05-03 8 views
3

私はExredisをデータベースとして使用している単純なWebアプリケーションを作成しています。 Exredisドキュメントを使用してクライアントを初期化するために言う:長時間実行される子プロセスのPIDはどこに保存しますか?

{:ok, conn} = Exredis.start_link 

私の質問は、私はconnを置けばいいのどこにあるのでしょうか?今私はExredis.start_link\1をDBクエリを作成する必要があるすべての関数の先頭に呼び出していますが、それは騒々しいと非効率の両方を感じています。私はconnを渡すことができますが、それは問題を私のルーターに移すだけです。

メインアプリケーションの起動時に一度起動して、アプリケーション全体で単一の接続を再利用するだけです。私はスーパーバイザに作業員として追加することができますが、残りのアプリケーションではPIDにアクセスする方法を理解できません。

答えて

5

connの代わりに、私はredisを扱うモジュールを1つ作成することをお勧めします。 (1秒が好ましい)あなたがそれをしたいかもしれない2つの方法があります:

1.新しい接続を開始し、閉じているRedisの照会たび:

defmodule Redis do 
     @redis_host "192.168.0.10" 
     @redis_port 6379 

     def query(...) do 
      {:ok, conn} = Exredis.start_link(@redis_host, @redis_port) 
      r = Exredis.query(conn, ...) 
      Exredis.stop(conn) 
      r 
     end 
    end 

2。いっそのこと、あなたはGenServer(優先溶液)でExredisをラップ:

defmodule Redis do 
     use GenServer 

     @redis_host "192.168.0.10" 
     @redis_port 6379 

     # External API 

     def start_link(state) do 
      GenServer.start_link(__MODULE__, state, name: __MODULE__) 
     end 

     def query(...) do 
      GenServer.call __MODULE__, { :query, ... } 
     end 

     # GenServer implementation 

     def init(state) do 
      {:ok, conn} = Exredis.start_link(@redis_host, @redis_port) 

      # conn becomes state available in handle_call/terminate 
      {:ok, conn} 
     end 

     def handle_call({ :query, ... }, conn) do 
      r = Exredis.query(conn, ...) 
      { :reply, r, conn } 
     end 

     def terminate(_reason, conn) do 
      Exredis.stop(conn) 
     end 
    end 

あなたは(初期状態としてnil渡し)上司に上記GenServerを追加します。そして、あなたは外部APIに固執します。 GenServerを直接扱うことは決してありません。将来的にモジュールを簡単に変更したり進化させることができます。あなたはGenServers hereについてもっと読むことができます。

+0

http://elixir-lang.org/docs/stable/elixir/GenServer.htmlによると、 'handle_call'は3つの引数をとります。 – xuanji

関連する問題