defmodule Tld.ListServer do @moduledoc """ GenServer to manage TLD list state. """ use GenServer alias Tld.IanaListParser require Logger defstruct list: [], list_url: "https://data.iana.org/TLD/tlds-alpha-by-domain.txt", version: 0 @impl true def init(%{} = state) do state = fetch_list(state) {:ok, state} end @impl true def handle_call({:get_list}, _from, %__MODULE__{} = state) do {:reply, state.list, state} end @doc """ Get TLD list from `Tld.ListServer` state. """ def get_list do GenServer.call(__MODULE__, {:get_list}) end @doc """ Standard `start_link/1` function to start `Tld.ListServer` as part of an `Application`’s `Supervisor` tree. """ def start_link(_opts) do GenServer.start_link(__MODULE__, %__MODULE__{}, name: __MODULE__) end defp fetch_list(%__MODULE__{} = state) do case Tld.HttpcListClient.fetch(state.list_url) do {:ok, body} -> Logger.info("Succesfully fetched TLD list from IANA.") {:ok, version, list} = IanaListParser.parse(body) state |> Map.put(:version, version) |> Map.put(:list, list) {:err, _metadata} -> Logger.error("Request to load TLD list failed.") state end end end