All Projects → grempe → Ex_rated

grempe / Ex_rated

Licence: other
ExRated, the Elixir OTP GenServer with the naughty name that allows you to rate-limit calls to any service that requires it.

Programming Languages

elixir
2628 projects

Projects that are alternatives of or similar to Ex rated

Node Rate Limiter Flexible
Node.js rate limit requests by key with atomic increments in single process or distributed environment.
Stars: ✭ 1,950 (+494.51%)
Mutual labels:  rate, rate-limiting
Bucket api
API for the bucket list
Stars: ✭ 83 (-74.7%)
Mutual labels:  api, bucket
Hammer
An Elixir rate-limiter with pluggable backends
Stars: ✭ 366 (+11.59%)
Mutual labels:  phoenix, rate-limiting
Redisratelimiter
Redis Based API Access Rate Limiter
Stars: ✭ 80 (-75.61%)
Mutual labels:  rate, rate-limiting
ticker-phoenix
Elixir Phoenix Stock Quotes API (IEX Trading)
Stars: ✭ 15 (-95.43%)
Mutual labels:  phoenix, otp
Elixirbooks
List of Elixir books
Stars: ✭ 1,021 (+211.28%)
Mutual labels:  phoenix, otp
Memento
Collect saved items from different sources around the web
Stars: ✭ 89 (-72.87%)
Mutual labels:  phoenix, otp
Guzzle Advanced Throttle
A Guzzle middleware that can throttle requests according to (multiple) defined rules. It is also possible to define a caching strategy, e.g. get the response from cache when the rate limit is exceeded or always get a cached value to spare your rate limits. Using wildcards in host names is also supported.
Stars: ✭ 120 (-63.41%)
Mutual labels:  api, rate-limiting
adaptive throttler
manages multiple throttlers with ability to ramp up and down
Stars: ✭ 31 (-90.55%)
Mutual labels:  rate-limiting, rate
flood-protection
Flood protection for realtime applications
Stars: ✭ 19 (-94.21%)
Mutual labels:  rate-limiting, rate
limio
A rate limiting library for Go centered around intuitive and idiomatic interfaces, and designed to limit silly window syndrome.
Stars: ✭ 51 (-84.45%)
Mutual labels:  rate-limiting, rate
throttle
Erlang/OTP application to rate limit resource access
Stars: ✭ 40 (-87.8%)
Mutual labels:  otp, rate-limiting
Annon.api
Configurable API gateway that acts as a reverse proxy with a plugin system.
Stars: ✭ 306 (-6.71%)
Mutual labels:  api, rate-limiting
Kanary
A minimalist web framework for building REST APIs in Kotlin/Java.
Stars: ✭ 319 (-2.74%)
Mutual labels:  api
Microcks
Kubernetes native tool for mocking and testing API and micro-services
Stars: ✭ 325 (-0.91%)
Mutual labels:  api
Fidl
A sane API for IDA Pro's decompiler. Useful for malware RE and vulnerability research
Stars: ✭ 319 (-2.74%)
Mutual labels:  api
Fortnite Api
Fortnite API, Get Stats, News And Status
Stars: ✭ 317 (-3.35%)
Mutual labels:  api
Ccxt
A JavaScript / Python / PHP cryptocurrency trading API with support for more than 100 bitcoin/altcoin exchanges
Stars: ✭ 22,501 (+6760.06%)
Mutual labels:  api
Zoonavigator
Web-based ZooKeeper UI / editor / browser
Stars: ✭ 326 (-0.61%)
Mutual labels:  api
Laravel5 Jsonapi
Laravel 5 JSON API Transformer Package
Stars: ✭ 313 (-4.57%)
Mutual labels:  api

ExRated

ExRated is:

  1. A port of the Erlang 'raterlimiter' project to Elixir.
  2. An OTP GenServer process that allows you to rate limit calls to something like an external API.
  3. The Hex.pm package with the naughty name.

You can learn more about the concept for this rate limiter in the Token Bucket article on Wikipedia

If you use the PhoenixFramework there is also a great blog post on Rate Limiting a Phoenix API by danielberkompas describing how to write a plug to use ExRated in your own API. Its fast and its easy.

Usage

Call the ExRated application with ExRated.check_rate/3. This function takes three arguments:

  1. A bucket name (Erlang term, typically String). You can have as many buckets as you need.
  2. A scale (Integer). The time scale in milliseconds that the bucket is valid for.
  3. A limit (Integer). How many actions you want to limit your app to in the time scale provided.

For example, if you have to enforce a rate limit of no more than 5 calls in 10 seconds to your API:

iex> ExRated.check_rate("my-rate-limited-api", 10_000, 5)
{:ok, 1}

The ExRated.check_rate function will return an {:ok, Integer} tuple if its OK to proceed with your rate limited function. The Integer returned is the current value of the incrementing counter showing how many times in the time scale window your function has already been called. If you are over limit a {:error, Integer} tuple will be returned where the Integer is always the limit you have specified in the function call.

Call the ExRated application with ExRated.inspect_bucket/3. This function takes the same three arguments as check_rate:

For example, if you want to inspect the bucket for your API:

iex> ExRated.inspect_bucket("my-rate-limited-api", 10_000, 5)
{0, 5, 2483, nil, nil}
iex> ExRated.check_rate("my-rate-limited-api", 10_000, 5)
{:ok, 1}
iex> ExRated.inspect_bucket("my-rate-limited-api", 10_000, 5)
{1, 4, 723, 1450282268397, 1450282268397}

The ExRated.inspect_bucket function will return a {count, count_remaining, ms_to_next_bucket, created_at, updated_at} tuple, count and count_remaining are integers, ms_to_next_bucket is the number of milliseconds before the bucket resets, created_at and updated_at are timestamps in millseconds.

Call the ExRated application with ExRated.delete_bucket/1. This function takes one argument:

  1. A bucket name (String). You can have as many buckets as you need.

For example, if you want to reset the counter for your API:

iex> ExRated.delete_bucket("my-rate-limited-api")
:ok

The ExRated.delete_bucket function will return an :ok on success or :error if the bucket doesn't exist

Installation

You can use ExRated in your projects in two steps:

  1. Add ExRated to your mix.exs dependencies:

    def deps do
      [{:ex_rated, "~> 1.2"}]
    end
    
  2. List :ex_rated in your application dependencies:

    def application do
      [applications: [:ex_rated]]
    end
    

You can also start the GenServer manually, and pass it custom config, with something like:

{:ok, pid} = GenServer.start_link(ExRated, [ {:timeout, 10_000}, {:cleanup_rate, 10_000}, {:persistent, false} ], [name: :ex_rated])

Alternatively, you can configure them in your config/config.exs (or other config) file like

config :ex_rated,
  timeout: 10_000,
  cleanup_rate: 10_000,
  persistent: false,
  name: :ex_rated,
  ets_table_name: :ets_rated_test_buckets

These args and their defaults are:

{:timeout, 90_000_000} : buckets older than this in milliseconds will be automatically pruned.

{:cleanup_rate, 60_000} : how often, in milliseconds, the bucket pruning process will be run.

{:ets_table_name, :ex_rated_buckets} : The atom name of the ETS table. This can be configured within your config files but not when starting the GenServer manually.

{:persistent, false} : Whether to persist ETS table to disk with DETS on server stop/restart.

[name: :ex_rated] : The registered name of the ExRated GenServer.

Testing

It is important that the OTP doesn't get automatically started by Mix.

mix test --no-start

Is it fast?

You can use the Benchfella library to do a quick performance test.

On a 2019 Macbook Pro (2.3 GHz 8-Core Intel Core i9, 64GB RAM) the lib can do 10,000,000 checks in less than 10s, averaging 0.89 µs/op (microseconds).

$ mix bench
Compiling 1 file (.ex)
Settings:
  duration:      1.0 s

## BasicBench
[10:45:54] 1/1: Basic Bench

Finished in 9.87 seconds

## BasicBench
benchmark na iterations   average time
Basic Bench    10000000   0.89 µs/op

Changes

v2.0.1

  • Add matrix tests for Elixir/OTP versions for Elixir >= 1.6. [@jechol]
  • Remove deprecated Supervisor.Spec.worker usage. [@jechol]
  • Remove init/1 from generated docs. [@jechol]
  • Update config example in README.md

v2.0.0

  • [BREAKING] Fixes #24 (Avoid GenServer Serialization) [@nabaskes, @benwilson512]
    • Improves performance from 2.26 µs/op to 0.89 µs/op (same hardware)
    • Breaking due to changed method for configuring ets_table_name if overriding.
  • Bucket names can be any Erlang term. Fixes #17 [@denvera]
  • Update ex_doc and ex2ms dependencies.
  • _ prefix unused variables to avoid compilation warnings.
  • Fix compilation warning with ets_table_name()
  • Added GitHub Elixir test action.

v1.3.3

  • Eliminate warning: function timestamp/1 is unused. [@brianberlin]

v1.3.2

  • Automatic application inference
  • Update ex_doc dependency
  • Update minimum Elixer to 1.6+
  • Update "Rate Limiting" blogpost URL reference

v1.3.1

  • Update ex2ms to v1.5

v1.3.0

  • Fix compilation warnings. [@walkr]
  • Start app properly with no args [@walkr]
  • Modify start_link to be callable by Supervisor.Spec.worker fun [@walkr]

v1.2.2

  • Update Elixir to v1.2
  • Update ex2ms to v1.4

v1.2.1

  • Change ETS Table to private.
  • Change ETS table name to a non-test name.

v1.2.0

  • Added {:persistent, false} option to server config to allow persisting data to disk.
  • Fixed minor compilation warning.

v1.1.0

  • Added delete_bucket/1 function. Takes a bucket name and removes it now instead of waiting for pruning (Nick Sanders).
  • Added inspect_bucket/3 function. Returns metadata about buckets (Nick Sanders).

v1.0.0

  • [BREAKING] Return {:error, limit} instead of {:fail, limit} to be a bit more idiomatic. Requires semver major version number change.
  • Support Elixir version 1.1 in addition to 1.0

v0.0.6

  • ExRated internally calls :erlang.system_time(:milli_seconds) provided by the new Time API in OTP 18 and greater if available, and will fall back gracefully to the old :erlang.now() in older versions. Thanks to Mitchell Henke (mitchellhenke) for the enhancement.

License

ExRated source code is released under Apache 2 License. Check LICENSE file for more information.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].