Current section
Files
Jump to
Current section
Files
src/glimiter.erl
-module(glimiter).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]).
-export([new_limiter/2, limit_guard/4, update/2]).
-export_type([limiter/1]).
-opaque limiter(HFM) :: {limiter,
gleam@dict:dict(HFM, list(birl:time())),
integer(),
birl@duration:duration()}.
-spec new_limiter(integer(), birl@duration:duration()) -> limiter(any()).
new_limiter(Count, Size) ->
{limiter, gleam@dict:new(), Count, Size}.
-spec limit_guard(limiter(HFS), HFS, HFU, fun(() -> HFU)) -> HFU.
limit_guard(Limiter, Key, Consequence, Alternetive) ->
_assert_subject = gleam@dict:get(erlang:element(2, Limiter), Key),
{ok, Times} = case _assert_subject of
{ok, _} -> _assert_subject;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"glimiter"/utf8>>,
function => <<"limit_guard"/utf8>>,
line => 27})
end,
case erlang:length(Times) < erlang:element(3, Limiter) of
true ->
Alternetive();
false ->
Consequence
end.
-spec add(limiter(HFV), HFV) -> gleam@dict:dict(HFV, list(birl:time())).
add(Limiter, Key) ->
Now = birl:now(),
case gleam@dict:get(erlang:element(2, Limiter), Key) of
{ok, Timestamps} ->
gleam@dict:insert(
erlang:element(2, Limiter),
Key,
[Now | Timestamps]
);
{error, _} ->
gleam@dict:insert(erlang:element(2, Limiter), Key, [Now])
end.
-spec filter_prev_window(limiter(HGA), HGA) -> gleam@dict:dict(HGA, list(birl:time())).
filter_prev_window(Limiter, Key) ->
_assert_subject = gleam@dict:get(erlang:element(2, Limiter), Key),
{ok, Times} = case _assert_subject of
{ok, _} -> _assert_subject;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"glimiter"/utf8>>,
function => <<"filter_prev_window"/utf8>>,
line => 49})
end,
Now = birl:now(),
New_times = gleam@list:filter(
Times,
fun(Time) ->
End_time = birl:add(Time, erlang:element(4, Limiter)),
case birl:compare(Now, End_time) of
lt ->
true;
eq ->
true;
_ ->
false
end
end
),
gleam@dict:insert(erlang:element(2, Limiter), Key, New_times).
-spec update(limiter(HFP), HFP) -> limiter(HFP).
update(Limiter, Key) ->
Limiter@1 = {limiter,
add(Limiter, Key),
erlang:element(3, Limiter),
erlang:element(4, Limiter)},
{limiter,
filter_prev_window(Limiter@1, Key),
erlang:element(3, Limiter@1),
erlang:element(4, Limiter@1)}.