kiola / lib /srh /redis /client_worker.ex
hiett
SSL support
f085bb2
defmodule Srh.Redis.ClientWorker do
use GenServer
def start_link(connection_info) do
GenServer.start_link(__MODULE__, connection_info, [])
end
def init(connection_info) do
Process.send(self(), :create_connection, [])
{
:ok,
%{
connection_info: connection_info,
redix_pid: nil
}
}
end
def redis_command(worker, command_array) do
GenServer.call(worker, {:redis_command, command_array})
end
def destroy_redis(worker) do
GenServer.cast(worker, {:destroy_redis})
end
def handle_call({:redis_command, command_array}, _from, %{redix_pid: redix_pid} = state)
when is_pid(redix_pid) do
case Redix.command(redix_pid, command_array) do
{:ok, res} ->
{:reply, {:ok, res}, state}
# Both connection errors and Redis command errors will be handled here
{:error, res} ->
{:reply, {:error, res}, state}
end
end
def handle_call(_msg, _from, state) do
{:reply, :ok, state}
end
def handle_cast({:destroy_redis}, %{redix_pid: redix_pid} = state) when is_pid(redix_pid) do
# Destroy the redis instance & ensure cleanup
Redix.stop(redix_pid)
Process.exit(redix_pid, :normal)
{:stop, :normal, %{state | redix_pid: nil}}
end
def handle_cast(_msg, state) do
{:noreply, state}
end
def handle_info(
:create_connection,
%{
connection_info: %{
"connection_string" => connection_string
}
} = state
)
when is_binary(connection_string) do
enable_ssl = String.starts_with?(connection_string, "rediss://")
socket_opts =
case enable_ssl do
true ->
[
customize_hostname_check: [
match_fun: :public_key.pkix_verify_hostname_match_fun(:https)
]
]
false ->
[]
end
# NOTE: Redix only seems to open the connection when the first command is sent
# This means that this will return :ok even if the connection string may not actually be connectable
{:ok, pid} =
Redix.start_link(connection_string,
ssl: enable_ssl,
socket_opts: socket_opts
)
{:noreply, %{state | redix_pid: pid}}
end
def handle_info(_msg, state) do
{:noreply, state}
end
end