Skip to content

Instantly share code, notes, and snippets.

@schmalz
Created September 13, 2017 15:04
Show Gist options
  • Save schmalz/cae280f39bdd337ec1513201ad7a7eb6 to your computer and use it in GitHub Desktop.
Save schmalz/cae280f39bdd337ec1513201ad7a7eb6 to your computer and use it in GitHub Desktop.
Designing for Scalability with Erlang/OTP - Ch 3 - Frequency Module - Elixir
defmodule Frequency do
@moduledoc"""
"""
# Client API
def start() do
Process.register(Process.spawn(&init/0, []), :frequency)
end
def stop() do
call(:stop)
end
def allocate() do
call(:allocate)
end
def deallocate(frequency) do
call({:deallocate, frequency})
end
# Server Callbacks
defp init() do
loop({initial_frequencies(), []})
end
# Private Functions
defp call(msg) do
send(:frequency, {:request, self(), msg})
receive do
{:reply, reply} ->
reply
end
end
defp reply(pid, reply) do
send(pid, {:reply, reply})
end
defp loop(frequencies) do
receive do
{:request, pid, :allocate} ->
{new_frequencies, reply} = allocate_frequency(frequencies, pid)
reply(pid, reply)
loop(new_frequencies)
{:request, pid, {:deallocate, frequency}} ->
reply(pid, :ok)
loop(deallocate_frequency(frequencies, frequency))
{:request, pid, :stop} ->
reply(pid, :ok)
end
end
defp allocate_frequency({[], _allocated} = frequencies, _pid) do
{frequencies, {:error, :no_frequency}}
end
defp allocate_frequency({[frequency | free], allocated}, pid) do
{{free, [{frequency, pid} | allocated]}, {:ok, frequency}}
end
defp deallocate_frequency({free, allocated}, frequency) do
{[frequency | free], List.keydelete(allocated, frequency, 0)}
end
defp initial_frequencies() do
[10, 11, 12, 13, 14, 15]
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment