Then add
worker(Redis, []),
to your supervision tree
defmodule Redis do | |
use Supervisor | |
def start_link() do | |
supervisor_name = Module.concat(__MODULE__, Supervisor) | |
Supervisor.start_link(__MODULE__, [], name: supervisor_name) | |
end | |
@doc false | |
def init([]) do | |
connection_string = System.get_env("REDIS_URL") || "redis://127.0.0.1:6379" | |
pool_size = (System.get_env("REDIS_POOL_SIZE") || "10") |> String.to_integer | |
max_overflow = (System.get_env("max_overflow") || "0") |> String.to_integer | |
%URI{host: host, port: port, userinfo: userinfo} = URI.parse(connection_string) | |
opts = Keyword.merge([], host: String.to_char_list(host)) | |
opts = Keyword.merge([], port: port) | |
if userinfo do | |
[user, pass] = String.split(userinfo, ":") | |
opts = Keyword.put(opts, :pass, String.to_char_list(pass)) | |
opts = Keyword.put(opts, :user, String.to_char_list(user)) | |
end | |
pool_name = Module.concat(__MODULE__, Pool) | |
pool_opts = [ | |
name: {:local, pool_name}, | |
worker_module: Redis.Worker, | |
size: pool_size, | |
max_overflow: max_overflow | |
] | |
children = [ | |
:poolboy.child_spec(pool_name, pool_opts, [opts]), | |
] | |
supervise children, strategy: :one_for_one | |
end | |
def cmd(command_list) do | |
:poolboy.transaction Redis.Pool, fn worker_pid -> | |
case GenServer.call(worker_pid, :conn) do | |
{:ok, conn_pid} -> | |
case :redo.cmd(conn_pid, command_list) do | |
{:error, reason} -> {:error, reason} | |
result -> result | |
end | |
{:error, reason} -> {:error, reason} | |
end | |
end | |
end | |
end |
defmodule Redis.Worker do | |
use GenServer | |
def start_link(opts) do | |
GenServer.start_link(__MODULE__, opts) | |
end | |
def init([opts]) do | |
Process.flag(:trap_exit, true) | |
{:ok, {:disconnected, opts}} | |
end | |
def handle_call(:conn, _, {:disconnected, opts}) do | |
case :redo.start_link(:undefined, opts) do | |
{:ok, pid} -> {:reply, {:ok, pid}, {pid, opts}} | |
{:error, err} -> {:reply, {:error, err}, {:disconnected, opts}} | |
end | |
end | |
def handle_call(:conn, _, {pid, opts}) do | |
{:reply, {:ok, pid}, {pid, opts}} | |
end | |
def handle_info({:EXIT, pid, _}, {pid, opts}) do | |
{:noreply, {:disconnected, opts}} | |
end | |
def handle_info(_, state) do | |
{:noreply, state} | |
end | |
def terminate(_reason, {:disconnected, _}), do: :ok | |
def terminate(_reason, {pid, _}), do: :redo.shutdown(pid) | |
end |