Created
September 28, 2015 08:39
-
-
Save mprymek/0a8f175d6c9201a81c62 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
defmodule TokenHolder do | |
require Logger | |
def start_link(user,passwd) do | |
Agent.start_link(fn -> | |
tok_time = get_token user, passwd | |
{user,passwd,tok_time} | |
end, name: __MODULE__) | |
end | |
# refresh the token if older that three seconds | |
@max_age 3000000 | |
def token do | |
Agent.get_and_update(__MODULE__, fn state={user,passwd,{token,retrieved}} -> | |
Logger.info "[PID=#{inspect self}=TokenHolder] Retrieving token" | |
now = :os.timestamp | |
age = :timer.now_diff(now, retrieved) | |
if(age < @max_age) do | |
Logger.info "Token age is #{age} - we can still use it" | |
# return old token and old state | |
{token,state} | |
else | |
Logger.info "Token age is #{age} - we must get a new one" | |
# retrieve new token, return it and return changed state | |
tok_time = {token,_} = get_token user, passwd | |
{token,{user,passwd,tok_time}} | |
end | |
end) | |
end | |
defp get_token(_user,_passwd) do | |
token = :random.uniform 100 | |
{token,:os.timestamp} | |
end | |
end | |
defmodule MyAPI do | |
@moduledoc "Simulates API access" | |
require Logger | |
@doc "Simulates accessing one API endpoint" | |
def users do | |
token = TokenHolder.token | |
Logger.info "[PID=#{inspect self}] We are accessing API using token #{token}" | |
:timer.sleep 1000 | |
Logger.info "[PID=#{inspect self}] We got answer." | |
["John","George","Martin"] | |
end | |
end | |
defmodule Main do | |
require Logger | |
def main do | |
# start logger | |
:ok = Application.ensure_started :logger | |
# start TokenHolder | |
{:ok,_} = TokenHolder.start_link "user", "secret" | |
# these two requests will be done in parallel | |
master = self | |
spawn_link(fn -> | |
users = MyAPI.users | |
Logger.info "users = #{inspect users}" | |
send master, :done | |
end) | |
spawn_link(fn -> | |
users = MyAPI.users | |
Logger.info "users = #{inspect users}" | |
send master, :done | |
end) | |
# wait for the requests to be finished | |
receive do :done -> :ok end | |
receive do :done -> :ok end | |
Logger.info "We are waiting now to simulate token expiration..." | |
:timer.sleep 5000 | |
# these two requests will be done in parallel with a new token | |
spawn_link(fn -> | |
users = MyAPI.users | |
Logger.info "users = #{inspect users}" | |
end) | |
spawn_link(fn -> | |
users = MyAPI.users | |
Logger.info "users = #{inspect users}" | |
end) | |
end | |
end | |
Main.main |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment