Skip to content

Instantly share code, notes, and snippets.

@schmalz
Created September 14, 2017 07:56
Show Gist options
  • Save schmalz/601a2e42b9fd42ace7a4cf66b2880886 to your computer and use it in GitHub Desktop.
Save schmalz/601a2e42b9fd42ace7a4cf66b2880886 to your computer and use it in GitHub Desktop.
Designing for Scalability with Erlang/OTP - Ch 4 - Frequency GenServer Module - Elixir/OTP
defmodule Frequency do
use GenServer
@moduledoc"""
Maintain a list of available radio frequencies and any associations between process identifiers and their
allocated frequencies.
"""
@initial_allocations []
@initial_frequencies [10, 11, 12, 13, 14, 15]
# Client API
def start_link() do
GenServer.start_link(__MODULE__, [], [name: __MODULE__])
end
def allocate() do
GenServer.call(__MODULE__, {:allocate, self()})
end
def deallocate(frequency) do
GenServer.cast(__MODULE__, {:deallocate, frequency})
end
# Server Callbacks
def init(_args) do
{:ok, {@initial_frequencies, @initial_allocations}}
end
def handle_call({:allocate, pid}, _from, frequencies) do
{new_frequencies, reply} = allocate_frequency(frequencies, pid)
{:reply, reply, new_frequencies}
end
def handle_cast({:deallocate, frequency}, frequencies) do
{:noreply, deallocate_frequency(frequencies, frequency)}
end
# Private Functions
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
end
@schmalz
Copy link
Author

schmalz commented Sep 14, 2017

The previous frequency example, rewritten using Elixir/OTP.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment