Skip to content

Instantly share code, notes, and snippets.

@adamgavlak
Created May 22, 2017 18:40
Show Gist options
  • Save adamgavlak/d0f2a18f733ab499dcaff5ef39bb2b46 to your computer and use it in GitHub Desktop.
Save adamgavlak/d0f2a18f733ab499dcaff5ef39bb2b46 to your computer and use it in GitHub Desktop.
defmodule RateLimiter do
use GenServer
require Logger
@rate_per_minute 30
@sweep_after :timer.seconds(60)
@bucket :rate_limiter_requests
## Client
def start_link do
GenServer.start_link(__MODULE__, [], name: __MODULE__)
end
def log(id) do
case :ets.update_counter(@bucket, id, {2, 1}, {id, 0}) do
count when count > @rate_per_minute -> {:error, :rate_limited}
_count -> :ok
end
end
## Server
def init(_) do
:ets.new(@bucket, [:set, :named_table, :public, read_concurrency: true, write_concurrency: true])
schedule_sweep()
{:ok, %{}}
end
def handle_info(:sweep, state) do
Logger.debug("Sweeping requests")
:ets.delete_all_objects(@bucket)
schedule_sweep()
{:noreply, state}
end
defp schedule_sweep do
Process.send_after(self(), :sweep, @sweep_after)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment