我在哪里存储PID以进行长时间运行的子进程?

Ben*_*tes 4 elixir

我正在编写一个使用Exredis作为数据库的简单Web应用程序.Exredis文档说要初始化客户端:

{:ok, conn} = Exredis.start_link
Run Code Online (Sandbox Code Playgroud)

我的问题是,我在哪里放conn?现在,我正在调用Exredis.start_link\1每个需要进行数据库查询的函数的顶部,但这样做既嘈杂又低效.我可以通过conn,但这只是将问题转移到我的路由器.

我想在我的主应用程序启动时启动它,并在我的应用程序中重复使用单个连接.我可以将它作为工作人员添加到我的主管,但我无法弄清楚如何在我的应用程序的其余部分访问PID.

小智 7

conn我建议您创建一个处理redis的模块,而不是四处传播.您可能有两种方法可以这样做(第二种方式是首选方式):

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
Run Code Online (Sandbox Code Playgroud)

2.更好的是,你将Exredis包装在GenServer中(首选解决方案):

    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
Run Code Online (Sandbox Code Playgroud)

您将上述GenServer添加到您的主管(将其nil作为初始状态传递).然后你坚持使用外部API.您永远不会直接处理GenServer,这使您将来更容易更改和改进模块.您可以在此处阅读有关GenServers的更多信息.