Popularity
1.3
Growing
Activity
0.0
Stable
8
1
1

Description

The Rate Limiter with Token Bucket algorithm

This is a fork of ExRated, but with some changes:

- the checkout and inspection always return the same result tuple - asynchronous counterparts for checkout, inspect and delete - configuration can be given on initialization and not only via application environment (useful when starting multiple rate limiters with different settings)

Monthly Downloads: 0
Programming language: Elixir
License: MIT License

Ralitobu alternatives and similar packages

Based on the "Miscellaneous" category.
Alternatively, view Ralitobu alternatives based on common mentions on social networks and blogs.

Do you think we are missing an alternative of Ralitobu or a related project?

Add another 'Miscellaneous' Package

README

Ralitobu

The Rate Limiter with Token Bucket algorithm

This is a fork of ExRated, but with some changes:

  • the checkout and inspection always return the same result tuple
  • asynchronous counterparts for checkout, inspect and delete
  • configuration can be given on initialization and not only via application environment (useful when starting multiple rate limiters with different settings)

Installation

In mix.exs:

  def deps do
    [{:ralitobu, "~> 0.1.0"}]
  end
  def application do
    [applications: [:ralitobu]]
  end

Usage

Checkouts

  • Ralitobu.checkout/3 (Ralitobu.checkout(id, limit, lifetime) using default server)
  • Ralitobu.checkout/4 (Ralitobu.checkout(server, id, limit, lifetime))

The result tuple format:

{success, counter, remaining_limit, total_limit, countdown, created_at, updated_at}
# 1st call:
Ralitobu.checkout("my-bucket", 3, 10_000)
#=> {:ok, 1, 2, 3, 7806, 1461432862194, 1461432862194}

# 3rd call:
Ralitobu.checkout("my-bucket", 3, 10_000)
#=> {:ok, 3, 0, 3, 7799, 1461432862194, 1461432862201}

# 4th call fails (over rate limit):
Ralitobu.checkout("my-bucket", 3, 10_000)
#=> {:error, 3, 0, 3, 7795, 1461432862194, 1461432862200}

Inspection

  • Ralitobu.inspect/3 (Ralitobu.inspect(id, limit, lifetime) using default server)
  • Ralitobu.inspect/4 (Ralitobu.inspect(server, id, limit, lifetime))

The result tuple format:

{success, counter, remaining_limit, total_limit, countdown, created_at, updated_at}
# multiple calls do not increment the counter:
Ralitobu.inspect("my-bucket", 3, 10_000)
#=> {:ok, 2, 3, 3, 4132, 1461432862194, 1461432862200}
Ralitobu.inspect("my-bucket", 3, 10_000)
#=> {:ok, 2, 3, 3, 4130, 1461432862194, 1461432862200}

# bucket does not exists:
Ralitobu.inspect("my-other-bucket", 3, 10_000)
#=> {:ok, 0, 3, 3, 9142, nil, nil}

Deletion

  • Ralitobu.delete/1 (Ralitobu.delete(id) using default server)
  • Ralitobu.delete/2 (Ralitobu.delete(server, id))

Result is either :ok or :error, depending if the bucket existed or not.

# bucket (still) exists:
Ralitobu.delete("my-bucket")
#=> :ok

# bucket is not present (anymore):
Ralitobu.delete("my-bucket")
#=> :error

New server instance

The application always starts a default server, but you can run your own instance(s) as well.

Ralitobu.start_server/2 (Ralitobu.start_server(configuration, gen_server_opts))

{:ok, server} = Ralitobu.start_server(
  [table_name: :another_ralitobu_table, timeout: 30_000_000, cleanup_rate: 15_000],
  [name: :another_ralitobu_server]
)

You must provide the name parameter for the GenServer options, otherwise it will take the default name and therefore not starting a new server. Also the table_name must be different, too.

Server configuration

  • table_name (atom): The name of the ETS table
  • timeout (integer): milliseconds; buckets older than (now - timeout) will be cleaned up (based on last update timestamp)
  • cleanup_rate (integer): milliseconds; the interval for the clean up task