Skip to content

4xposed/minirate

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

19 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Elixir CI

Minirate

A dead simple distributed rate limiting library in Elixir using Mnesia.

What is it?

A distributed rate limiter with a focus on readable and well tested code.

The counter is syncronized over all connected nodes

iex(test2@127.0.0.1)19> Minirate.check_limit("download", "user_1", 100)
{:allow, 1}
iex(test1@127.0.0.1)14> Minirate.check_limit("download", "user_1", 100)
{:allow, 2}

Installation

Minirate is availabe as a package in Hex, just add it to your mix.exs file:

def deps
  [{:minirate, "~> 0.1"}]
end

and add it to your extra applications:

def applications do
[
  extra_applications: [:minirate]
]

Configuration

Minirate needs to be configured using Mix.Config.

For example, in config/config.exs:

config :minirate,
  mnesia_table: :rate_limiter,
  expiry_ms: 60_000
  cleanup_period_ms: 10_000

mnesia_table specifies which table will Mnesia use to write the counters. expiry_ms specifies the counter life in millisecconds (for example to have rates like x request every 10 seconds, you would set expiry_ms to 10_000) cleanup_period_ms specifies how often minirate will clean expired counters from the mnesia database

Usage

With Minirate you can rate limit any action on your application.

The module Minirate the function check_limit(action_name, identifier, limit)

An Example:

@download_limit 1_000

def download_file(file, user_id) do
  case Minirate.check_limit("download_file", user_id, @download_limit) do
    {:allow, _count} ->
      # Logic to download the file

    {:block, _reason} ->
      # Logic when the limit has been reached

    {:skip, _reason} ->
     # Skip will only happen if there's a problem with your nodes or mnesia setup and a count cannot be determined.
  end

Using Minirate.Plug

Minirate.Plug can rate-limit actions in your web application using the ip address of the requester.

You can just put in the pipeline of your web application something like this:

plug Minirate.Plug, [action: action, limit: 10_000]

or for more flexibilty:

plug Minirate.Plug, [action: "custom_action", limit: 10_000] when action == :update or action == :create