defmodule ReverseProxy.LoadBalancer do @moduledoc """ Our Load Balancer. It rotates the servers from which we get a response. We start the GenServer with the config file filled with hosts and upstreams. """ use GenServer #Module API def start_link(upstreams) do GenServer.start_link(__MODULE__, upstreams, name: __MODULE__) end @doc """ The public API to select our next server to hit. It just takes a hots that we need to hit. Exapmle: ReverseProxy.LoadBalancer.select(load.com) """ def select(host) do GenServer.call(__MODULE__, {:select, host}) end @doc """ Initializes the gen server with all the upstreams. """ def init(upstreams) do {:ok, upstreams} end @doc """ The server callback for the `select` function. It rotates the servers every time we hit them with a request. """ def handle_call({:select, host}, _from, upstreams) do [h | tail] = upstreams[host] rotate_servers = tail ++ [h] upstreams = %{upstreams | host => rotate_servers} {:reply, h, upstreams} end end