Skip to content

Instantly share code, notes, and snippets.

@glesica
Last active August 29, 2015 14:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save glesica/50f2f8cbfa0fc82a105e to your computer and use it in GitHub Desktop.
Save glesica/50f2f8cbfa0fc82a105e to your computer and use it in GitHub Desktop.
GenServer implementation that wraps a function in order to allow calls to be rate limited.
defmodule Auscrape.RateLimit do
use GenServer
use Timex
def start_link(fun, interval, opts \\ []) do
GenServer.start_link(__MODULE__, {fun, interval}, opts)
end
def call_fun(server, args) do
GenServer.call(server, {:call, args}, :infinity)
end
def call_fun(server) do
call_fun(server, [])
end
defp current_time() do
Time.now |> Time.to_msecs |> round
end
def init({fun, interval}) do
{:ok, {fun, interval, current_time, 0}}
end
def handle_call({:call, args}, from, {fun, interval, start_time, tick}) do
wait_time = (start_time + tick * interval - current_time) |> max(0)
fn ->
receive do
after
wait_time ->
GenServer.reply(from, {:ok, apply(fun, args)})
end
end |> spawn
{:noreply, {fun, interval, start_time, tick + 1}}
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment