64 lines
1.7 KiB
Elixir
64 lines
1.7 KiB
Elixir
defmodule TokenServer do
|
|
use GenServer
|
|
require Logger
|
|
alias TokenServer.ApiClient
|
|
|
|
# Server
|
|
|
|
@impl GenServer
|
|
@spec init(any()) :: {:ok, DateTime.t()}
|
|
def init(_) do
|
|
:ets.new(:token_store, [:named_table, read_concurrency: true])
|
|
expires_at = get_and_store_token()
|
|
{:ok, expires_at}
|
|
end
|
|
|
|
@impl GenServer
|
|
@spec handle_info(any(), DateTime.t()) :: {:noreply, DateTime.t()}
|
|
def handle_info(:refresh, _expires_at) do
|
|
expires_at = get_and_store_token()
|
|
{:noreply, expires_at}
|
|
end
|
|
|
|
def handle_info(msg, expires_at) do
|
|
Logger.info("Received unknown message: #{inspect(msg)}")
|
|
{:noreply, expires_at}
|
|
end
|
|
|
|
@impl GenServer
|
|
@spec handle_call(:force_refresh, GenServer.from(), DateTime.t()) :: {:reply, :ok, DateTime.t()}
|
|
def handle_call(:force_refresh, _from, _expires_at) do
|
|
expires_at = get_and_store_token()
|
|
{:reply, :ok, expires_at}
|
|
end
|
|
|
|
defp get_and_store_token() do
|
|
{token, expires_at} = ApiClient.get_token()
|
|
:ets.insert(:token_store, {:token, token})
|
|
|
|
next_refresh = DateTime.add(expires_at, -5, :minute)
|
|
ms_to_refresh = DateTime.diff(next_refresh, DateTime.utc_now(), :millisecond)
|
|
Process.send_after(self(), :refresh, ms_to_refresh)
|
|
|
|
expires_at
|
|
end
|
|
|
|
# Client
|
|
|
|
@doc """
|
|
A function to start this GenServer as part of the supervision tree, registered with the
|
|
name of the module.
|
|
"""
|
|
@spec start_link(any()) :: GenServer.on_start()
|
|
def start_link(_) do
|
|
GenServer.start_link(__MODULE__, nil, name: __MODULE__)
|
|
end
|
|
|
|
@spec get() :: String.t()
|
|
def get(), do: :ets.lookup_element(:token_store, :token, 2)
|
|
|
|
@spec force_refresh() :: :ok
|
|
def force_refresh() do
|
|
GenServer.call(__MODULE__, :force_refresh)
|
|
end
|
|
end
|