Packages

This is a GenServer-ish implementation of a Choice Context. That is a process that accepts a value during the specified period of time and refuses to do so after the timeout has elapsed.

Current section

Files

Jump to
choice_context lib choice_context.ex
Raw

lib/choice_context.ex

defmodule ChoiceContext do
defstruct [:mode, :choices]
use GenServer
# API
def start_link(timeout, choices) do
__MODULE__ |> GenServer.start_link({timeout, choices}, name: __MODULE__)
end
def start(timeout, choices) do
__MODULE__ |> GenServer.start({timeout, choices}, name: __MODULE__)
end
def accept(server \\ __MODULE__, choice) do
server |> GenServer.call({:accept, choice})
end
# Callbacks
def init({timeout, choices}) do
self() |> Process.send_after(:timeout, timeout)
{:ok, %__MODULE__{mode: :active, choices: choices}}
end
def handle_call({:accept, choice}, _from, %__MODULE__{mode: :active, choices: choices} = state) do
result =
if choice in choices do
{:stop, :normal, {:choice, choice}, state}
else
{:reply, {:reply, "Valid choices are: *#{choices |> Enum.join(~S|, |)}*"}, state}
end
end
def handle_call(_, _from, %__MODULE__{mode: :inactive} = state) do
{:stop, :normal, {:reply, "Too late, the choise context has ended."}, state}
end
def handle_info(:timeout, state) do
{:noreply, %{state|mode: :inactive}}
end
end