Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/elixir/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Elixir 如何处理API的不同速率限制?_Elixir - Fatal编程技术网

Elixir 如何处理API的不同速率限制?

Elixir 如何处理API的不同速率限制?,elixir,Elixir,我为一个API构建了一个包装器,该API一直在工作,但现在该公司决定为其端点实施不同的速率限制,因为这是一个游戏,他们有服务器,每个服务器都有不同的限制,例如,EUW服务器有一个限制,而北美有另一个限制,但他们为他们的玩家提供相同的信息。现在,我实现了一个GenServer,它负责处理这些不同的速率限制,但我无法找到一种方法来处理开发人员密钥的速率限制,这些密钥是20r/1s或100r/2m。默认情况下,我实现了第一个限制,每秒20个请求,但这并不总是正确的。我用Exrate来处理这些请求 我希

我为一个API构建了一个包装器,该API一直在工作,但现在该公司决定为其端点实施不同的速率限制,因为这是一个游戏,他们有服务器,每个服务器都有不同的限制,例如,EUW服务器有一个限制,而北美有另一个限制,但他们为他们的玩家提供相同的信息。现在,我实现了一个GenServer,它负责处理这些不同的速率限制,但我无法找到一种方法来处理开发人员密钥的速率限制,这些密钥是20r/1s或100r/2m。默认情况下,我实现了第一个限制,每秒20个请求,但这并不总是正确的。我用Exrate来处理这些请求

我希望完成的工作:一种处理开发关键点短期和长期限制的方法

在处理请求的函数中,我有一些我认为需要删除的东西,现在它只是一个占位符

  def get(region, rest, opt) do
    url = Map.get(@endpoint, region)

    if Mix.env() == :prod do # This part
      # Enforcing the time and amount of requests per method if
      # opts provided
      opt_time = Keyword.get(opt, :time)
      opt_amount = Keyword.get(opt, :amount)

      region
      |> ExRated.check_rate(opt_time, opt_amount)
      |> parse(url, rest)
    else
      region
      |> ExRated.check_rate(time(), amount())
      |> parse(url, rest)
    end
  end
上面的else语句是我想要修复的语句,以支持这两个开发限制

根据第一条评论进行编辑:

defmodule Godfist.LeagueRates do
  @moduledoc false

  # Handles checking the information passed and assigning the correct
  # limit to the request.

  use GenServer

  alias Godfist.HTTP

  # Rates for different servers.
  @rates [
    # "League" endpoints/servers
    euw: {300, 60_000},
    na: {270, 60_000},
    eune: {135, 60_000},
    br: {90, 60_000},
    kr: {90, 60_000},
    lan: {80, 60_000},
    las: {80, 60_000},
    tr: {60, 60_000},
    oce: {55, 60_000},
    jp: {35, 60_000},
    ru: {35, 60_000},
    # other endpoints
    match: {500, 10_000},
    matchlist: {1000, 10_000},
    champion_masteries_runes: {400, 60_000},
    static: {10, 3_600_000},
    other: {20_000, 10_000}
  ]

  # API
  def start_link,
    do: GenServer.start_link(__MODULE__, %{}, name: :league_limit)

  def handle_rate(region, rest, endpoint \\ nil) do
    GenServer.call(:league_limit, {:handle_rate, region, rest, endpoint})
  end

  # Server
  def init(state),
    do: {:ok, state}

  # This first handler is matching on the "Leagues" endpoints,
  # that's why endpoint is nil, that arg is meant to be used with
  # the other endpoints (Matches, Runes, etc...)
  def handle_call({:handle_rate, region, rest, endpoint}, _from, state)
  when is_nil(endpoint) do
    {time, amount} = Keyword.get(@rates, region)

    {:reply, HTTP.get(region, rest, time: time, amount: amount), state}
  end

  def handle_call({:handle_rate, region, rest, endpoint}, _from, state) do
    {time, amount} = Keyword.get(@rates, endpoint)

    {:reply, HTTP.get(region, rest, time: time, amount: amount), state}
  end
end

每个区域可以保留两个计数器,一个用于每秒20个请求的限制,另一个用于每两分钟100个请求。在发送请求之前,您可以检查是否达到了任何一个限制,如果达到了,则中止发送请求

case {ExRated.check_rate("#{region}-1", 20, 1), ExRated.check_rate("#{region}-2", 100, 120)} do
  {{:ok, _}, {:ok, _}} ->
    # neither limit has been hit
  _ ->
    # one or both limits have been hit
end

根据
区域的值计算
时间
金额
的值怎么样?例如,
{time,amount}=案例区域do“US”->{1,2};“EUW”->{3,4}结束
并将其传递给
ExRated
?@Dogbert哦,不,我已经这样做了,我将使用GenServer编辑答案,我所做的,我正在讨论开发密钥中的两种限制情况。有什么好的解决方案可以支持开发限制,即每秒20个请求或每2分钟100个请求。啊。像这样的怎么样<代码>大小写{ExRated.check_rate({region}-1,20,1),ExRated.check_rate({region}-2,100,120)}do{{:好的,{好的,{好的,{好的,{好的,}->。。。结束
。每次都会增加两个计数器,如果其中任何一个达到限制,您可以中止请求。嗯,我想我可以处理这个问题,让我看看我的想法@DogbertYes,我在你评论时使用了这个解决方案,谢谢!