Updated packages: - bandit: 1.10.3 → 1.10.4 - phoenix_live_view: 1.1.27 → 1.1.28 - phoenix_pubsub_redis: 3.0.1 → 3.1.0 - oban_met: 1.0.6 → 1.1.0 (vendored) - oban_web: 2.11.8 → 2.12.1 (vendored) All tests passing (8923 tests, 0 failures). Reviewed-on: graham/towerops-web#194
83 lines
2.3 KiB
Elixir
83 lines
2.3 KiB
Elixir
defmodule Oban.Web.Metrics do
|
|
@moduledoc false
|
|
|
|
alias Oban.Met
|
|
|
|
@states ~w(available executing scheduled retryable)a
|
|
|
|
@doc """
|
|
Fetch latest metric counts with optional fallback to previous values.
|
|
|
|
When `Met.latest/3` returns an empty map (which happens when the reporter's
|
|
`check_interval` exceeds the recorder's lookback window), this function
|
|
returns the `previous` value instead. This prevents UI flickering in the
|
|
sidebar when metrics briefly show as zero between reporter broadcasts.
|
|
"""
|
|
def latest(name, series, opts \\ [], previous \\ %{}) do
|
|
result = Met.latest(name, series, opts)
|
|
|
|
if result == %{} and previous != %{} do
|
|
previous
|
|
else
|
|
result
|
|
end
|
|
end
|
|
|
|
@doc """
|
|
Fetch state counts for the jobs sidebar.
|
|
"""
|
|
def state_counts(name, ordered_states, previous \\ []) do
|
|
counts = latest(name, :full_count, [group: "state"], counts_to_map(previous))
|
|
|
|
if counts == %{} and previous != [] do
|
|
previous
|
|
else
|
|
for state <- ordered_states do
|
|
%{name: state, count: Map.get(counts, state, 0)}
|
|
end
|
|
end
|
|
end
|
|
|
|
defp counts_to_map(previous) when is_list(previous) do
|
|
Map.new(previous, fn %{name: name, count: count} -> {name, count} end)
|
|
end
|
|
|
|
defp counts_to_map(previous), do: previous
|
|
|
|
@doc """
|
|
Fetch queue counts for a specific state.
|
|
"""
|
|
def queue_counts(name, state, previous \\ %{}) do
|
|
latest(name, :full_count, [group: "queue", filters: [state: to_string(state)]], previous)
|
|
end
|
|
|
|
@doc """
|
|
Fetch state counts filtered by queue for queue detail view.
|
|
"""
|
|
def queue_state_counts(name, queue, previous \\ %{}) do
|
|
latest(name, :full_count, [group: "state", filters: [queue: queue]], previous)
|
|
end
|
|
|
|
@doc """
|
|
Fetch counts for all queue states needed for the queues sidebar.
|
|
"""
|
|
def all_queue_counts(name, previous \\ %{}) do
|
|
Map.new(@states, fn state ->
|
|
{state, queue_counts(name, state, previous[state])}
|
|
end)
|
|
end
|
|
|
|
@doc """
|
|
Extract previous counts from a list of queue structs for caching.
|
|
"""
|
|
def extract_queue_counts(queues) when is_list(queues) do
|
|
for state <- @states, into: %{} do
|
|
per_queue =
|
|
for queue <- queues, into: %{}, do: {queue.name, Map.get(queue.counts, state, 0)}
|
|
|
|
{state, per_queue}
|
|
end
|
|
end
|
|
|
|
def extract_queue_counts(_), do: %{}
|
|
end
|