defmodule Buzzword.Cache.Server do
@moduledoc """
A process that loads a map of buzzwords from an external file and caches it
for expedient access. The cache is automatically refreshed every hour.
"""
use GenServer
alias __MODULE__
alias Buzzword.Cache.Loader
alias Buzzword.Cache
@typedoc "Server state"
@type state :: {Cache.buzzwords(), reference}
@refresh_interval :timer.minutes(60)
@spec start_link(term) :: GenServer.on_start()
def start_link(:ok = _init_arg),
do: GenServer.start_link(Server, :ok, name: Server)
## Private functions
@spec state :: state
defp state do
{Loader.read_buzzwords(),
self() |> Process.send_after(:refresh, @refresh_interval)}
end
## Callbacks
@spec init(term) :: {:ok, state}
def init(:ok = _init_arg), do: {:ok, state()}
@spec handle_call(atom, GenServer.from(), state) ::
{:reply, Cache.buzzwords(), state}
def handle_call(:get_buzzwords, _from, {buzzwords, _timer_ref} = state),
do: {:reply, buzzwords, state}
@spec handle_info(term, state) :: {:noreply, state}
def handle_info(:refresh, {_buzzwords, timer_ref} = _state) do
Process.cancel_timer(timer_ref, info: false)
{:noreply, state()}
end
def handle_info(_message, state), do: {:noreply, state}
end