项目作者: nsweeting

项目描述 :
A general purpose Elixir throttle utility.
高级语言: Elixir
项目地址: git://github.com/nsweeting/throttle.git
创建时间: 2017-05-16T22:13:27Z
项目社区:https://github.com/nsweeting/throttle

开源协议:

下载


Throttle

A general throttle utility. Mainly used to throttle inbound or outbound requests.

Installation

Add the following to your list of dependencies in mix.exs:

  1. def deps do
  2. [{:throttle, "~> 0.1.2"}]
  3. end

Setup

As of now, Throttle only provides a Redis-backed cache. To configure your Redis connection, please add the following to config/config.exs.

  1. config :redis_connection_pool, [
  2. host: "127.0.0.1",
  3. port: 6379,
  4. password: "",
  5. db: 0,
  6. reconnect: :no_reconnect,
  7. pool_name: :"Redis.Pool",
  8. pool_size: 10,
  9. pool_max_overflow: 1
  10. ]

Or use with the full_url option.

  1. config :redis_connection_pool, [
  2. full_url: "redis://127.0.0.1:6379",
  3. reconnect: :no_reconnect,
  4. pool_name: :"Redis.Pool",
  5. pool_size: 10,
  6. pool_max_overflow: 1
  7. ]

You can also add throttle contexts to your config. This will allow us to access them by atom-only in the future.

  1. config :throttle, [
  2. contexts: [
  3. # This would create a throttle context keyed under "example1" that allows 3 requests per second.
  4. example1: {"example1", :rps, 3}
  5. # This would create a throttle context keyed under "example2" that allows 30 requests per minute.
  6. example2: {"example2", :rpm, 30}
  7. # This would create a throttle context keyed under "example3" that allows 300 requests per hour.
  8. example2: {"example3", :rph, 300}
  9. # This would create a throttle context keyed under "example4" that allows 1 request every 3 seconds.
  10. example2: {"example3", :interval, 3}
  11. # This would create a throttle context keyed under "example5" using a leaky bucket that adds 1 token every second (rate),
  12. # to a maximum of 40 (max), with each request costing 2 tokens (cost).
  13. example2: {"example3", :bucket, [rate: 1, max: 40, cost: 2]}
  14. ]
  15. ]

Usage

Throttle provides a number of ways in which to control requests. They are:

  • Requests per second (rps)
  • Requests per minute (rpm)
  • Requests per hour (rph)
  • Seconds Between Request (interval)
  • Leaky Bucket (bucket)

Assuming we use one of our above contexts, we can now start using our throttles:

  1. case Throttle.allow?(:example2) do
  2. {:ok, result} -> IO.puts "OK"
  3. {:error, result} -> IO.puts "Error"
  4. end

Using config contexts means that each request is made under the same key. In the example above, this would be “example2”.

Alternatively, we can simply pass a context directly into the allow? function.

  1. key = "1" # This could be a user id
  2. case Throttle.allow?({key, :rps, 3}) do
  3. {:ok, result} -> IO.puts "OK"
  4. {:error, result} -> IO.puts "Error"
  5. end

In all cases, a context must be structured as follows:

  1. {key, type, value} = {"key", :rps, 3}

Using With Plug

Throttle provides a plug that can be used for API throttling. It can be used as follows:

  1. defmodule MyRouter do
  2. use Plug.Router
  3. plug Throttle.Plug, {"mysite", :bucket, [rate: 1, max: 40, cost: 2]}
  4. plug :match
  5. plug :dispatch
  6. match _ do
  7. send_resp(conn, 200, "hello")
  8. end
  9. end

The above would end up creating a leaky bucket throttle. The key would be a join between “mysite” and the IP address of the incoming request.