Skip to content

Instantly share code, notes, and snippets.

@joshnuss
Last active December 24, 2015 10:39
Show Gist options
  • Save joshnuss/6785804 to your computer and use it in GitHub Desktop.
Save joshnuss/6785804 to your computer and use it in GitHub Desktop.
A small load balancer. Spawns a pool of local or remote processes and then acts as a wrapper, forwarding messages to the pool either randomly or sequentially.
defmodule LoadBalancer do
def start(mod, func, args, count, strategy // :random) do
pids = spawn_many(count, mod, func, args)
run(strategy, pids)
end
def run(strategy, pids) do
receive do
message ->
pid = Enum.first(pids)
IO.puts("Load balancer #{inspect self} received #{inspect message}. Forwarding to #{inspect pid}")
pid <- message
run(strategy, reorder(pids, strategy))
end
end
defp spawn_many(0, _mod, _func, _args), do: []
defp spawn_many(n, mod, func, args) do
[spawn_link(mod, func, args) | spawn_many(n-1, mod, func, args)]
end
defp reorder(pids, :random), do: Enum.shuffle(pids)
defp reorder([head|tail], :round_robin), do: tail ++ [head]
defp reorder(_pids, :load_average), do: raise "not yet implemented"
end
defmodule TestServer do
def start, do: run
def run do
receive do
msg -> IO.puts("Test server #{inspect self} received #{inspect msg}")
end
run
end
end
# create a load balancer for 100 instances of TestServer.start/0, accessed in a random fashion:
balancer = spawn(LoadBalancer, :start, [TestServer, :start, [], 100, :random])
# send a message to the balancer:
balancer <- "balance this"
# spawn a load balancer that will in turn spawn another 10 load balancers. each balancer will boot 10 Test Servers (total: 100 test servers, 11 load balancers)
balancer = spawn(LoadBalancer, :start,
[LoadBalancer, :start,
[TestServer, :start, [], 10], 10])
balancer <- "here's something"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment