Current section

Files

Jump to
xandra lib xandra cluster load_balancing_policy random.ex
Raw

lib/xandra/cluster/load_balancing_policy/random.ex

defmodule Xandra.Cluster.LoadBalancingPolicy.Random do
@moduledoc """
A simple `Xandra.Cluster.LoadBalancingPolicy` that picks hosts at random.
This load-balancing policy doesn't make any attempt to be smart: it doesn't take
data center or tokens into consideration, and considers all available nodes.
This policy is available since Xandra *v0.15.0*.
"""
@moduledoc since: "0.15.0"
alias Xandra.Cluster.Host
@behaviour Xandra.Cluster.LoadBalancingPolicy
@impl true
def init([] = _options) do
[]
end
@impl true
def host_added(hosts, new_host) do
Enum.uniq_by([{new_host, :up}] ++ hosts, fn {host, _status} -> Host.to_peername(host) end)
end
@impl true
def host_up(hosts, new_host) do
Enum.map(hosts, fn {host, status} ->
if host_match?(host, new_host), do: {host, :up}, else: {host, status}
end)
end
@impl true
def host_removed(hosts, host) do
Enum.reject(hosts, fn {existing_host, _status} -> host_match?(existing_host, host) end)
end
@impl true
def host_connected(hosts, new_host) do
Enum.map(hosts, fn {host, status} ->
if host_match?(host, new_host), do: {host, :connected}, else: {host, status}
end)
end
@impl true
def host_down(hosts, host_down) do
Enum.map(hosts, fn {host, status} ->
if host_match?(host, host_down), do: {host, :down}, else: {host, status}
end)
end
@impl true
def query_plan(hosts) do
connected_hosts = for {host, :connected} <- hosts, do: host
{Enum.shuffle(connected_hosts), hosts}
end
@impl true
def hosts_plan(hosts) do
up_hosts = for {host, status} when status in [:up, :connected] <- hosts, do: host
{Enum.shuffle(up_hosts), hosts}
end
defp host_match?(%Host{} = host1, %Host{} = host2) do
host1.address == host2.address and host1.port == host2.port
end
end