pgsql: move logic out of watcher, wire mode of operation
This commit is contained in:
parent
9ddd999ed8
commit
c33ffd5139
5 changed files with 54 additions and 22 deletions
|
@ -1,10 +1,45 @@
|
||||||
defmodule HAHandler.PGSQL do
|
defmodule HAHandler.PGSQL do
|
||||||
@supervisor HAHandler.PGSQL.Supervisor
|
@supervisor HAHandler.PGSQL.Supervisor
|
||||||
|
@version_query "SELECT version();"
|
||||||
|
@is_in_recovery_query "SELECT pg_is_in_recovery();"
|
||||||
|
|
||||||
def status() do
|
def get_instances() do
|
||||||
watchers = Supervisor.which_children(@supervisor)
|
watchers = Supervisor.which_children(@supervisor)
|
||||||
for {_id, pid, _type, _modules} <- watchers do
|
for {hostname, pid, _type, _modules} <- watchers do
|
||||||
GenServer.call(pid, :status)
|
{hostname, pid}
|
||||||
end
|
end
|
||||||
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
|
end
|
||||||
|
|
|
@ -9,7 +9,12 @@ defmodule HAHandler.PGSQL.Supervisor do
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
def init(instances) do
|
def init(instances) do
|
||||||
children = Enum.map(instances, fn conf -> {PGSQLWatcher, conf} end)
|
children = Enum.map(instances, fn conf ->
|
||||||
|
%{
|
||||||
|
id: Keyword.get(conf, :hostname),
|
||||||
|
start: {PGSQLWatcher, :start_link, [conf]}
|
||||||
|
}
|
||||||
|
end)
|
||||||
|
|
||||||
opts = [ strategy: :one_for_one ]
|
opts = [ strategy: :one_for_one ]
|
||||||
Supervisor.init(children, opts)
|
Supervisor.init(children, opts)
|
||||||
|
|
|
@ -3,7 +3,7 @@ defmodule HAHandler.PGSQL.Watcher do
|
||||||
require Logger
|
require Logger
|
||||||
|
|
||||||
def start_link(opts) do
|
def start_link(opts) do
|
||||||
GenServer.start_link(__MODULE__, opts, name: __MODULE__)
|
GenServer.start_link(__MODULE__, opts)
|
||||||
end
|
end
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
|
@ -23,20 +23,7 @@ defmodule HAHandler.PGSQL.Watcher do
|
||||||
end
|
end
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
def handle_call(:status, _from, %{backend: backend, hostname: hostname} = state) do
|
def handle_call({:execute, query, params}, _from, %{backend: backend} = state) do
|
||||||
result = case Postgrex.query(backend, "SELECT version();", []) do
|
{:reply, Postgrex.query(backend, query, params), state}
|
||||||
{: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: "Unhandled error"}
|
|
||||||
end
|
|
||||||
|
|
||||||
{:reply, result, state}
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -19,9 +19,12 @@ defmodule HAHandler.Web.Controller do
|
||||||
def index(conn) do
|
def index(conn) do
|
||||||
{:ok, hostname} = :net_adm.dns_hostname(:net_adm.localhost)
|
{:ok, hostname} = :net_adm.dns_hostname(:net_adm.localhost)
|
||||||
|
|
||||||
|
haproxy_stats = HAProxy.get_stats([hide_error: true])
|
||||||
|
pgsql_stats = PGSQL.get_stats()
|
||||||
|
|
||||||
assigns = [
|
assigns = [
|
||||||
haproxy_stats: HAProxy.get_stats([hide_error: true]),
|
haproxy_stats: haproxy_stats,
|
||||||
pgsql_status: PGSQL.status(),
|
pgsql_status: pgsql_stats,
|
||||||
hostname: hostname,
|
hostname: hostname,
|
||||||
otp_app: HAHandler.otp_app(),
|
otp_app: HAHandler.otp_app(),
|
||||||
version: HAHandler.version(),
|
version: HAHandler.version(),
|
||||||
|
|
|
@ -109,6 +109,7 @@
|
||||||
<th>Hostname</th>
|
<th>Hostname</th>
|
||||||
<th>Version</th>
|
<th>Version</th>
|
||||||
<th>Status</th>
|
<th>Status</th>
|
||||||
|
<th>Operation</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
|
@ -117,6 +118,7 @@
|
||||||
<td><%= entry[:hostname] %></td>
|
<td><%= entry[:hostname] %></td>
|
||||||
<td><%= entry[:version] %></td>
|
<td><%= entry[:version] %></td>
|
||||||
<td><%= entry[:status] %></td>
|
<td><%= entry[:status] %></td>
|
||||||
|
<td><%= entry[:mode] %></td>
|
||||||
</tr>
|
</tr>
|
||||||
<% end %>
|
<% end %>
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|
Loading…
Reference in a new issue