Skip to content

Commit 241abd4

Browse files
authored
Merge pull request #286 from dylantirandaz/enhance-telemetry-and-distribution
Enhance telemetry and distribution strategy typespecs
2 parents 94615f7 + d0efd3a commit 241abd4

File tree

6 files changed

+48
-2
lines changed

6 files changed

+48
-2
lines changed

lib/horde/dynamic_supervisor_impl.ex

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,9 +104,13 @@ defmodule Horde.DynamicSupervisorImpl do
104104
end
105105

106106
def handle_call(:get_telemetry, _from, state) do
107+
members_info = Map.values(state.members_info)
108+
107109
telemetry = %{
108110
global_supervised_process_count: size_of(state.processes_by_id),
109-
local_supervised_process_count: state.local_process_count
111+
local_supervised_process_count: state.local_process_count,
112+
alive_members_count: Enum.count(members_info, &match?(%{status: :alive}, &1)),
113+
total_members_count: length(members_info)
110114
}
111115

112116
{:reply, telemetry, state}

lib/horde/uniform_distribution.ex

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ defmodule Horde.UniformDistribution do
88
the same process on the same node.
99
"""
1010

11+
@impl true
12+
@spec choose_node(Supervisor.child_spec(), [Horde.DistributionStrategy.member()]) ::
13+
{:ok, Horde.DistributionStrategy.member()} | {:error, :no_alive_nodes}
1114
def choose_node(child_spec, members) do
1215
identifier = :erlang.phash2(Map.drop(child_spec, [:id]))
1316

@@ -28,5 +31,7 @@ defmodule Horde.UniformDistribution do
2831
end
2932
end
3033

34+
@impl true
35+
@spec has_quorum?([Horde.DistributionStrategy.member()]) :: boolean()
3136
def has_quorum?(_members), do: true
3237
end

lib/horde/uniform_quorum_distribution.ex

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ defmodule Horde.UniformQuorumDistribution do
88
"""
99
require Integer
1010

11+
@impl true
12+
@spec choose_node(Supervisor.child_spec(), [Horde.DistributionStrategy.member()]) ::
13+
{:ok, Horde.DistributionStrategy.member()} | {:error, :no_alive_nodes | :quorum_not_met}
1114
def choose_node(child_spec, members) do
1215
if has_quorum?(members) do
1316
Horde.UniformDistribution.choose_node(child_spec, members)
@@ -16,6 +19,8 @@ defmodule Horde.UniformQuorumDistribution do
1619
end
1720
end
1821

22+
@impl true
23+
@spec has_quorum?([Horde.DistributionStrategy.member()]) :: boolean() | nil
1924
def has_quorum?([]), do: false
2025

2126
def has_quorum?(members) do

lib/horde/uniform_random_distribution.ex

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ defmodule Horde.UniformRandomDistribution do
99
@doc """
1010
Selects a random alive node.
1111
"""
12+
@impl true
13+
@spec choose_node(Supervisor.child_spec(), [Horde.DistributionStrategy.member()]) ::
14+
{:ok, Horde.DistributionStrategy.member()} | {:error, :no_alive_nodes}
1215
def choose_node(_identifier, members) do
1316
members
1417
|> Enum.filter(&match?(%{status: :alive}, &1))
@@ -29,5 +32,7 @@ defmodule Horde.UniformRandomDistribution do
2932
Quorum checks are not enforced, so the process will be
3033
(re)started on both sides of a netsplit.
3134
"""
35+
@impl true
36+
@spec has_quorum?([Horde.DistributionStrategy.member()]) :: boolean()
3237
def has_quorum?(_members), do: true
3338
end

test/supervisor_telemetry_poller_test.exs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,15 @@ defmodule SupervisorTelemetryPollerTest do
1313

1414
def init(_), do: {:ok, %{}}
1515

16-
def handle_call(:get_telemetry, _, state), do: {:reply, %{metrics: 1}, state}
16+
def handle_call(:get_telemetry, _, state) do
17+
{:reply,
18+
%{
19+
global_supervised_process_count: 2,
20+
local_supervised_process_count: 1,
21+
alive_members_count: 3,
22+
total_members_count: 3
23+
}, state}
24+
end
1725
end
1826

1927
setup do

test/uniform_distribution_test.exs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,25 @@ defmodule UniformDistributionTest do
3232
end
3333
end
3434

35+
property "is deterministic for the same input" do
36+
check all(
37+
identifier <- string(:alphanumeric, min_length: 1),
38+
member_count <- integer(1..10)
39+
) do
40+
members =
41+
Enum.map(1..member_count, fn i ->
42+
%{node_id: i, status: :alive, name: :"node_#{i}", pid: :pid}
43+
end)
44+
45+
child_spec = %{id: identifier, start: {identifier}}
46+
47+
result1 = Horde.UniformDistribution.choose_node(child_spec, members)
48+
result2 = Horde.UniformDistribution.choose_node(child_spec, members)
49+
50+
assert result1 == result2
51+
end
52+
end
53+
3554
property "returns error if no alive nodes are available" do
3655
member =
3756
ExUnitProperties.gen all(

0 commit comments

Comments
 (0)