Packages
horde
0.9.1
0.10.0
0.9.1
0.9.0
0.8.7
0.8.6
0.8.5
0.8.4
0.8.3
0.8.2
0.8.1
0.8.0
0.8.0-rc.1
0.7.1
0.7.0
0.6.1
0.6.0
0.6.0-rc.1
0.5.0
0.5.0-rc.12
0.5.0-rc.11
0.5.0-rc.10
0.5.0-rc.9
0.5.0-rc.8
0.5.0-rc.7
0.5.0-rc.6
0.5.0-rc.5
0.5.0-rc.4
0.5.0-rc.3
0.5.0-rc.2
0.5.0-rc.1
0.4.0-rc.2
0.4.0-rc.1
0.3.0
0.3.0-rc1
0.2.3
0.2.2
0.2.1
0.2.0
0.1.5
0.1.4
0.1.3
0.1.2
0.1.1
0.1.0
Distributed supervisor & process registry built with DELTA-CRDTs
Current section
Files
Jump to
Current section
Files
lib/horde/uniform_quorum_distribution.ex
defmodule Horde.UniformQuorumDistribution do
@behaviour Horde.DistributionStrategy
@moduledoc """
Distributes processes to nodes uniformly using a hash ring. Contains a quorum mechanism to handle netsplits.
It enforces a quorum and will shut down all processes on a node if it is split from the rest of the cluster.
"""
require Integer
def choose_node(child_spec, members) do
if has_quorum?(members) do
Horde.UniformDistribution.choose_node(child_spec, members)
else
{:error, :quorum_not_met}
end
end
def has_quorum?([]), do: false
def has_quorum?(members) do
case active_nodes(members) do
[] ->
nil
members ->
alive_count = Enum.count(members, &match?(%{status: :alive}, &1))
alive_count / Enum.count(members) > 0.5
end
end
defp active_nodes(members) do
nodes =
members
|> Enum.reject(&match?(%{status: :shutting_down}, &1))
|> Enum.sort_by(& &1.name)
node_count = Enum.count(nodes)
if node_count > 0 && Integer.is_even(node_count) do
[_ | nodes] = nodes
nodes
else
nodes
end
end
end