Skip to content

Instantly share code, notes, and snippets.

@elbow-jason
Created February 10, 2018 18:09
Show Gist options
  • Save elbow-jason/628a8163e67ad6f95e746401604e9821 to your computer and use it in GitHub Desktop.
Save elbow-jason/628a8163e67ad6f95e746401604e9821 to your computer and use it in GitHub Desktop.
A token refreshing simulated GenServer
defmodule MyTokenRefresher do
use GenServer
def start_link(_) do
GenServer.start_link(__MODULE__, nil, name: __MODULE__)
end
def init(_) do
async_fetch_token()
{:ok, %{token: nil}}
end
def handle_info({:update_token, token}, state) do
IO.inspect(token, label: "TOKEN")
set_fetch_timer(token["expires"])
{:noreply, Map.put(state, :token, token)}
end
def handle_info(:fetch_token, state) do
async_fetch_token()
{:noreply, state}
end
def handle_call(:get_token, _from, state) do
resp = case state.token do
nil ->
{:error, :no_token}
token ->
{:ok, token}
end
{:reply, resp, state}
end
def get_token do
GenServer.call(__MODULE__, :get_token)
end
defp minutes_in_the_future(minutes) do
DateTime.utc_now()
|> DateTime.to_unix
|> Kernel.+(minutes * 60)
|> trunc
|> DateTime.from_unix
|> case do
{:ok, datetime} -> datetime
end
end
defp async_fetch_token() do
pid = self()
spawn_link(fn ->
# HTTPoison.post goes here
# simulated with a sleep
:timer.sleep(2000)
token = %{"expires" => minutes_in_the_future(0.1), "text" => "abc123"}
send(pid, {:update_token, token})
end)
end
defp milliseconds(seconds) do
seconds * 1000
end
defp set_fetch_timer(expires_at) do
now = DateTime.utc_now |> DateTime.to_unix() |> milliseconds
exp = expires_at |> DateTime.to_unix |> milliseconds
interval = exp - now
IO.inspect(interval, label: "INTERVAL")
Process.send_after(self(), :fetch_token, interval)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment