Last active
August 29, 2015 14:05
-
-
Save dgoldie/6c1f0db6060536e534e5 to your computer and use it in GitHub Desktop.
rate limit resource problem
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 Connection.Yahoo.ConsumerAgent do | |
require Logger | |
@name {:global, YahooConsumerAgent } | |
def name do | |
@name | |
end | |
@doc """ | |
Starts a new consumer key agent. | |
""" | |
def start_link(opts) do | |
Agent.start_link(fn -> | |
last = Connection.Yahoo.Consumer.total_keys - 1 | |
dict = HashDict.new |> Dict.put( :current, 0) | |
key_range = 0..last | |
Enum.reduce(key_range, dict, fn x,dict -> Dict.put(dict, x, 0) end) | |
end, | |
opts) | |
end | |
@doc """ | |
Gets the current consumer key from the agent`. | |
And updates the count of tries for that key. | |
""" | |
def get do | |
Agent.get_and_update(@name, fn dict -> | |
current = HashDict.get(dict, :current) | |
dict = Dict.update!(dict, current, fn x -> x + 1 end) | |
{current, dict} | |
end) | |
end | |
@doc """ | |
Switch to next consumer key after rejection. | |
""" | |
def get_after_rejection do | |
Agent.get_and_update(@name, fn dict -> | |
new_value = switch_consumer_keys(dict) | |
IO.inspect new_value | |
{ new_value, HashDict.put(dict, :current, new_value) } | |
end) | |
end | |
@doc """ | |
Get the count of tries for the current consumer key. | |
""" | |
def get_current_count do | |
Agent.get(@name, fn dict -> | |
current = HashDict.get(dict, :current) | |
HashDict.get(dict, current) | |
end) | |
end | |
@doc """ | |
Puts the `value` for the given `key` in the dictionary in `agent`. | |
""" | |
def put(key, value) do | |
Agent.update(@name, &HashDict.put(&1, key, value)) | |
end | |
defp switch_consumer_keys(dict) do | |
old_index = HashDict.get(dict, :current) | |
count = HashDict.get(dict, old_index) | |
Logger.info "Consumer Key ##{old_index}: is switched at count #{count}" | |
new_index = old_index |> Connection.Yahoo.Consumer.next_key_id | |
HashDict.put(dict, new_index, 0) | |
new_index | |
end | |
# def init(num) do | |
# for n <- 1..num, into: HashDict.new do | |
# {n, 0} | |
# end | |
# end | |
end |
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 Connection.Yahoo.ConsumerAgentTest do | |
use ExUnit.Case, async: true | |
alias Connection.Yahoo.ConsumerAgent | |
setup do | |
# Logger.start | |
{:ok, agent} = ConsumerAgent.start_link name: ConsumerAgent.name | |
{:ok, agent: agent} | |
end | |
test "get current consumer key" do | |
assert ConsumerAgent.get == 0 | |
end | |
test "switches current consumer key from 0 to 1" do | |
assert ConsumerAgent.get_after_rejection == 1 | |
end | |
test "switches from last consumer key to first" do | |
first_key = 0 | |
last_key = Connection.Yahoo.Consumer.last_key | |
ConsumerAgent.put(:current, last_key) | |
assert ConsumerAgent.get == last_key | |
assert ConsumerAgent.get_after_rejection == first_key | |
end | |
test "counting keys used" do | |
for _n <- 1..6, do: ConsumerAgent.get | |
assert ConsumerAgent.get_current_count == 6 | |
end | |
end |
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 Connection.Yahoo.ConsumerSupervisor do | |
use Supervisor | |
def start_link do | |
Supervisor.start_link(__MODULE__, :ok) | |
end | |
@agent_name YahooConsumerAgent | |
def init(:ok) do | |
children = [ | |
worker(Connection.Yahoo.ConsumerAgent, [[name: {:global, @agent_name}]]) | |
] | |
supervise(children, strategy: :one_for_one) | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment