defmodule RNS.PathRequestStore do @moduledoc """ Stores the tags of all sent/received path requests. This is so path requests are only answered to once, and so a message can be sent to a process with the answer to the path request. """ use GenServer @spec start_link(any()) :: {:ok, pid()} def start_link(opts) do GenServer.start_link(__MODULE__, opts, name: __MODULE__) end @doc "Adds a path request tag to the store." @spec add(RNS.Packet.PathRequest.tag()) :: :ok | {:error, :tag_exists} def add(tag) do GenServer.cast(__MODULE__, {:add, tag}) end @doc "Checks if a tag exists in the tag list." @spec exists?(RNS.Packet.PathRequest.tag()) :: boolean() def exists?(tag) do GenServer.call(__MODULE__, {:exists?, tag}) end @impl true def init(_opts) do {:ok, {[], []}} end @impl true def handle_cast({:add, tag}, {handlers, tags}) do new_tags = if tag in tags do tags else new_tags = [tag | tags] if length(new_tags) > 64 do List.delete_at(new_tags, -1) else new_tags end end new_state = {handlers, new_tags} {:noreply, new_state} end @impl true def handle_call({:exists?, tag}, _from, {_, tags} = state) do {:reply, tag in tags, state} end end