ha-handler/lib/ha_handler/pgsql.ex

53 lines
1.4 KiB
Elixir

defmodule HAHandler.PGSQL do
@supervisor HAHandler.PGSQL.Supervisor
@version_query "SELECT version();"
@is_in_recovery_query "SELECT pg_is_in_recovery();"
def get_instances() do
watchers = Supervisor.which_children(@supervisor)
for {hostname, pid, _type, _modules} <- watchers do
{hostname, pid}
end
end
def get_version({hostname, pid}) do
case GenServer.call(pid, {:execute, @version_query, []}) do
{:ok, %Postgrex.Result{rows: [[raw_version_string]]}} ->
version =
case Regex.run(~r/^PostgreSQL (\d+\.\d+)/, raw_version_string) do
[_, version_number] -> version_number
_ -> "unknown"
end
%{hostname: hostname, version: version, status: "up"}
{:error, %DBConnection.ConnectionError{message: _msg, reason: err}} ->
%{hostname: hostname, version: "unknown", status: err}
_ ->
%{hostname: hostname, version: "unknown", status: :unknown}
end
end
def get_operation_mode({_hostname, pid}) do
case GenServer.call(pid, {:execute, @is_in_recovery_query, []}) do
{:ok, %Postgrex.Result{rows: [[false]]}} ->
:primary
{:ok, %Postgrex.Result{rows: [[true]]}} ->
:secondary
_ ->
:unknown
end
end
def get_stats() do
get_instances()
|> Enum.map(fn instance ->
get_version(instance) |> Map.put(:mode, get_operation_mode(instance))
end)
end
end