Erlang token bucket rate limiter
Erlang
-module(token_bucket).
-export([new/2, allow/2]).
new(Rate, Burst) ->
#{rate => Rate, burst => Burst, tokens => float(Burst), ts => now_ms()}.
allow(C = #{rate := Rate, burst := Burst, tokens := T, ts := Last}) ->
Now = now_ms(),
Tokens = min(float(Burst), T + (Now - Last) * Rate / 1000),
case Tokens >= 1.0 of
true -> {true, C#{tokens => Tokens - 1, ts => Now}};
false -> {false, C#{tokens => Tokens, ts => Now}}
end.
now_ms() -> erlang:monotonic_time(millisecond).