RateLimiterMan.LeakyBucket (Rate Limiter Man v0.1.1)

View Source

A leaky-bucket rate limiter that processes requests at a fixed rate (e.g. 1 request per second).

TODO

Add more documentation.

Summary

Functions

Returns a specification to start this module under a supervisor.

Functions

child_spec(init_arg)

Returns a specification to start this module under a supervisor.

See Supervisor.

make_request(api_provider, request_handler, response_handler \\ nil, opts \\ [])

Call a function using the rate limiter.

Receiving a response

To receive a response from the rate limiter, you must pass in the following opts:

  • from - The PID of the process that will receive the response (e.g. self())
  • request_id - A unique identifier (e.g. a random number, or the x-request-id header)

Then, add a receive block where you want the response to be received:

iex> receive do
...>   {:ok, %{request_id: request_id, resp: resp}} when request_id == your_request_id ->
...>     resp
...> after
...>   30_000 -> {:error, :gateway_timeout}
...> end

Examples

Get a reference to the desired rate limiter for the following examples:

iex> rate_limiter = RateLimiterMan.get_rate_limiter(YourProject.RateLimiter)

Make a request using the rate limiter:

iex> rate_limiter.make_request(
...>   _api_provider = YourProject.RateLimiter,
...>   _request_handler = {IO, :puts, ["Hello world!"]}
...> )
:ok

Or, make a request using the rate limiter, and have the rate limiter send the response back to the caller via message passing:

# Generate a unique request ID
iex> request_id = System.unique_integer()

# Make the request
iex> rate_limiter.make_request(
...>   _api_provider = YourProject.RateLimiter,
...>   _request_handler = {String, :duplicate, ["Hello world! ", 2]},
...>   _response_handler = nil,
...>   from: self(),
...>   request_id: unique_request_id
...> )
:ok

# Receive the response for further processing
iex> receive do
...>   {:ok, %{request_id: request_id, resp: resp}} when request_id == unique_request_id ->
...>     resp
...> after
...>   30_000 -> {:error, :gateway_timeout}
...> end
"Hello world! Hello world! "

skip_response_handler(res)

start_link(opts)