kiola / lib /srh /redis /client.ex
hiett
SSL support
f085bb2
defmodule Srh.Redis.Client do
use GenServer
alias Srh.Redis.ClientRegistry
alias Srh.Redis.ClientWorker
@idle_death_time 1000 * 60 * 15 # 15 minutes
def start_link(max_connections, connection_info) do
GenServer.start_link(__MODULE__, {max_connections, connection_info}, [])
end
def init({max_connections, connection_info}) do
Process.send(self(), :create_registry, [])
{
:ok,
%{
registry_pid: nil,
idle_death_ref: nil,
max_connections: max_connections,
connection_info: connection_info
}
}
end
def find_worker(client) do
GenServer.call(client, {:find_worker})
end
def borrow_worker(client) do
GenServer.call(client, {:borrow_worker})
end
def return_worker(client, pid) do
GenServer.cast(client, {:return_worker, pid})
end
def destroy_workers(client) do
GenServer.cast(client, {:destroy_workers})
end
def handle_call({:find_worker}, _from, %{registry_pid: registry_pid} = state)
when is_pid(registry_pid) do
{:ok, worker} = ClientRegistry.find_worker(registry_pid)
Process.send(self(), :reset_idle_death, [])
{:reply, worker, state}
end
def handle_call({:borrow_worker}, _from, %{registry_pid: registry_pid} = state)
when is_pid(registry_pid) do
{:ok, worker} = ClientRegistry.borrow_worker(registry_pid)
Process.send(self(), :reset_idle_death, [])
{:reply, worker, state}
end
def handle_call(_msg, _from, state) do
{:reply, :ok, state}
end
def handle_cast({:return_worker, pid}, %{registry_pid: registry_pid} = state)
when is_pid(pid) and is_pid(registry_pid) do
ClientRegistry.return_worker(registry_pid, pid)
{:noreply, state}
end
def handle_cast({:destroy_workers}, state) do
ClientRegistry.destroy_workers(state.registry_pid)
{:stop, :normal, state}
end
def handle_cast(_msg, state) do
{:noreply, state}
end
def handle_info(:idle_death, state) do
ClientRegistry.destroy_workers(state.registry_pid)
{:stop, :normal, state}
end
def handle_info(:reset_idle_death, state) do
if state.idle_death_ref != nil do
Process.cancel_timer(state.idle_death_ref)
end
{
:noreply,
%{state | idle_death_ref: Process.send_after(self(), :idle_death, @idle_death_time)}
}
end
def handle_info(:create_registry, state) do
{:ok, pid} = ClientRegistry.start_link()
# Spin up three workers
for _ <- 1..Map.get(state.connection_info, "max_connections", 3) do
{:ok, worker} = ClientWorker.start_link(state.connection_info)
ClientRegistry.add_worker(pid, worker)
end
{:noreply, %{state | registry_pid: pid}}
end
def handle_info(_msg, state) do
{:noreply, state}
end
end