2017-01-04 4 views
0
私はエリクサーでGenServerを構築してい

、のは、それがこのキューについては、このElixir GenServerの依存性注入はどのようにして行いますか?

defmodule Queue do 
    use GenServer 

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

    def push(server, msg) do 
    GenServer.call(server, {:subscribe, channel, last_id}) 
    end 

    def pop(server) do 
    GenServer.call(server, {:pop, channel, last_id}) 
    end 

    # handlers here ... 
end 

のような単純なキューの言わせて、私は

  • Redisの
    • PostgreSQLのように、異なるストレージバックエンドを提供するワン
    • インメモリ
    • ファイル

    など。ここに質問があります。このGenServerに依存性注入を行うにはどうしたらいいですか?理想的には私は、データベースバックエンド

    {:ok, db_queue} = Queue.start_link(:DBQueue, db_process_pid) 
    

    のために、このような異なるバックエンドとのキューを作成したいとRedisのために、私は別のバックエンドと同じキューサーバーを作成することができ、このように、この

    {:ok, redis_queue} = Queue.start_link(:RedisQueue, redis_process_pid) 
    

    を好むかもしれません。 ElixirがGenServerの依存性注入を行うベストプラクティスは何ですか?

    答えて

    3

    pidだけを保存したい場合は、GenServer状態を使用して保存することができます。 handle_*コールバック関数からアクセスできます。あなたがしたいようにあなたは今、それを起動することができ

    defmodule Queue do 
        use GenServer 
    
        def start_link(name, pid) do 
        GenServer.start_link(__MODULE__, pid, name: name) 
        end 
    
        def init(pid), do: {:ok, pid} 
    
        ... 
    end 
    

    :あなたのhandle_*コールバックで

    {:ok, db_queue} = Queue.start_link(:DBQueue, db_process_pid) 
    

    そして、ちょうどである(状態にアクセス例えば、ここでキューのようになる方法です最後の引数から、この場合のPID):

    def handle_call({:subscribe, channel, last_id}, from, pid) do 
        # use the pid and the message to construct a reply 
        reply = ... 
        {:reply, reply, pid} 
    end 
    

    あなたが言うようにも、モジュールをより多くのものを保存したい場合は、単にのようなマップにどこでもpidを変更。すべてのErlang項を状態として使用できます。

    関連する問題