Add initial PoC

This commit is contained in:
Adam Millerchip 2024-06-28 18:51:49 +09:00
parent 31ea2a9314
commit 3ba98e7f81
3 changed files with 69 additions and 14 deletions

View file

@ -1,18 +1,64 @@
defmodule TokenServer do
@moduledoc """
Documentation for `TokenServer`.
"""
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 """
Hello world.
## Examples
iex> TokenServer.hello()
:world
A function to start this GenServer as part of the supervision tree, registered with the
name of the module.
"""
def hello do
:world
@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

View file

@ -0,0 +1,10 @@
defmodule TokenServer.ApiClient do
def get_token do
Process.sleep(3000)
token = Base.encode32(:rand.bytes(10))
expires_at = DateTime.utc_now() |> DateTime.add(1, :hour)
{token, expires_at}
end
end

View file

@ -8,8 +8,7 @@ defmodule TokenServer.Application do
@impl true
def start(_type, _args) do
children = [
# Starts a worker by calling: TokenServer.Worker.start_link(arg)
# {TokenServer.Worker, arg}
{TokenServer, nil}
]
# See https://hexdocs.pm/elixir/Supervisor.html