Vendor oban_web 2.12.1 and oban_met 1.1.0 (taken from the towerops-web2 vendor tree), bump oban to ~> 2.21, and mount the Oban dashboard at /admin/oban behind the existing require_admin on_mount hook. Adds an admin-only "Oban" nav link and extends the Dockerfile to copy vendor/ before deps.get so production builds pick up the path dependencies.
141 lines
2.8 KiB
Elixir
141 lines
2.8 KiB
Elixir
defmodule Oban.Met.Values.Gauge do
|
|
@moduledoc """
|
|
One or more non-negative integers captured over time.
|
|
"""
|
|
|
|
alias __MODULE__, as: Gauge
|
|
|
|
@encoder if Code.ensure_loaded?(JSON.Encoder), do: JSON.Encoder, else: Jason.Encoder
|
|
|
|
@derive @encoder
|
|
defstruct data: 0
|
|
|
|
@type t :: %__MODULE__{data: [non_neg_integer()]}
|
|
|
|
@doc """
|
|
Initialize a new gauge.
|
|
|
|
## Examples
|
|
|
|
iex> Gauge.new(1).data
|
|
[1]
|
|
|
|
iex> Gauge.new([1, 2]).data
|
|
[1, 2]
|
|
"""
|
|
@spec new(non_neg_integer() | [non_neg_integer()]) :: t()
|
|
def new(data) when is_integer(data) and data > 0 do
|
|
%Gauge{data: [data]}
|
|
end
|
|
|
|
def new(data) when is_list(data) do
|
|
%Gauge{data: data}
|
|
end
|
|
|
|
@doc """
|
|
Add to the gauge.
|
|
|
|
## Examples
|
|
|
|
iex> 1
|
|
...> |> Gauge.new()
|
|
...> |> Gauge.add(1)
|
|
...> |> Gauge.add(1)
|
|
...> |> Map.fetch!(:data)
|
|
[3]
|
|
"""
|
|
@spec add(t(), pos_integer()) :: t()
|
|
def add(%Gauge{data: [head | tail]}, value) when value > 0 do
|
|
%Gauge{data: [head + value | tail]}
|
|
end
|
|
|
|
@doc """
|
|
Merges two gauges into a one.
|
|
|
|
## Examples
|
|
|
|
Merging two gauge retains all values:
|
|
|
|
iex> gauge_1 = Gauge.new([1, 2])
|
|
...> gauge_2 = Gauge.new([2, 3])
|
|
...> Gauge.merge(gauge_1, gauge_2).data
|
|
[1, 2, 2, 3]
|
|
"""
|
|
@spec merge(t(), t()) :: t()
|
|
def merge(%Gauge{data: data_1}, %Gauge{data: data_2}) do
|
|
%Gauge{data: data_1 ++ data_2}
|
|
end
|
|
|
|
@doc """
|
|
Compute the quantile for a gauge.
|
|
|
|
## Examples
|
|
|
|
With single values:
|
|
|
|
iex> Gauge.quantile(Gauge.new([1, 2, 3]), 1.0)
|
|
3
|
|
|
|
iex> Gauge.quantile(Gauge.new([1, 2, 3]), 0.5)
|
|
2
|
|
"""
|
|
@spec quantile(t(), float()) :: non_neg_integer()
|
|
def quantile(%Gauge{data: data}, ntile) do
|
|
length = length(data) - 1
|
|
|
|
data
|
|
|> Enum.sort()
|
|
|> Enum.at(floor(length * ntile))
|
|
end
|
|
|
|
@doc """
|
|
Compute the sum for a gauge.
|
|
|
|
## Examples
|
|
|
|
iex> Gauge.sum(Gauge.new(3))
|
|
3
|
|
|
|
iex> Gauge.sum(Gauge.new([1, 2, 3]))
|
|
6
|
|
"""
|
|
@spec sum(t()) :: non_neg_integer()
|
|
def sum(%Gauge{data: data}), do: Enum.sum(data)
|
|
|
|
@doc """
|
|
Union two gauges into a single value.
|
|
|
|
## Examples
|
|
|
|
Merging two gauge results in a single value:
|
|
|
|
iex> gauge_1 = Gauge.new([1, 2])
|
|
...> gauge_2 = Gauge.new([2, 3])
|
|
...> Gauge.union(gauge_1, gauge_2).data
|
|
[8]
|
|
"""
|
|
@spec union(t(), t()) :: t()
|
|
def union(%Gauge{data: data_1}, %Gauge{data: data_2}) do
|
|
data =
|
|
(data_1 ++ data_2)
|
|
|> Enum.sum()
|
|
|> List.wrap()
|
|
|
|
%Gauge{data: data}
|
|
end
|
|
|
|
@doc """
|
|
Initialize a gauge struct from a stringified map, e.g. encoded JSON.
|
|
|
|
## Examples
|
|
|
|
iex> Gauge.new(2)
|
|
...> |> Oban.JSON.encode!()
|
|
...> |> Oban.JSON.decode!()
|
|
...> |> Gauge.from_map()
|
|
...> |> Map.fetch!(:data)
|
|
[2]
|
|
"""
|
|
@spec from_map(%{optional(String.t()) => term()}) :: t()
|
|
def from_map(%{"data" => data}), do: %Gauge{data: data}
|
|
end
|