• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

emqx / emqx / 12741272085

13 Jan 2025 05:33AM UTC coverage: 82.355%. First build
12741272085

Pull #14475

github

web-flow
Merge b56877530 into 0fc8025be
Pull Request #14475: refactor(limiter): refactor and simplify the limiter

199 of 249 new or added lines in 21 files covered. (79.92%)

57201 of 69457 relevant lines covered (82.35%)

15186.26 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

87.88
/apps/emqx/src/emqx_limiter/src/emqx_limiter_container.erl
1
%%--------------------------------------------------------------------
2
%% Copyright (c) 2021-2025 EMQ Technologies Co., Ltd. All Rights Reserved.
3
%%
4
%% Licensed under the Apache License, Version 2.0 (the "License");
5
%% you may not use this file except in compliance with the License.
6
%% You may obtain a copy of the License at
7
%%
8
%%     http://www.apache.org/licenses/LICENSE-2.0
9
%%
10
%% Unless required by applicable law or agreed to in writing, software
11
%% distributed under the License is distributed on an "AS IS" BASIS,
12
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
%% See the License for the specific language governing permissions and
14
%% limitations under the License.
15
%%--------------------------------------------------------------------
16

17
-module(emqx_limiter_container).
18

19
%% API
20
-export([create_by_names/3, create/1, check/2]).
21

22
-type index() :: pos_integer().
23

24
-type container() ::
25
    undefined
26
    | #{
27
        emqx_limiter:limiter_name() => [index()],
28
        index() => emqx_limiter:limiter()
29
    }.
30

31
-export_type([container/0]).
32

33
%%--------------------------------------------------------------------
34
%%  API
35
%%--------------------------------------------------------------------
36
create_by_names(Name, undefined, Zone) ->
37
    create_by_names(Name, #{}, Zone);
584✔
38
create_by_names(Names, Cfg, Zone) ->
39
    do_create_by_names(Names, Cfg, Zone, []).
18,054✔
40

41
-spec create([{emqx_limiter:limiter_name(), [emqx_limiter:limiter()]}]) -> container().
42
create(Groups) ->
43
    do_create(Groups, 1, #{}).
18,054✔
44

45
-spec check([{emqx_limiter:limiter_name(), non_neg_integer()}], container()) ->
46
    {boolean(), container()}.
47
check(_Needs, undefined) ->
48
    {true, undefined};
201,348✔
49
check(Needs, Container) ->
50
    do_check(Needs, Container, []).
40✔
51

52
%%--------------------------------------------------------------------
53
%%  Internal functions
54
%%--------------------------------------------------------------------
55
do_create_by_names([Name | Names], Cfg, Zone, Acc) ->
56
    Private =
33,570✔
57
        case emqx_limiter:get_cfg(Name, Cfg) of
58
            undefined ->
59
                [];
33,550✔
60
            LimiterCfg ->
61
                [emqx_limiter_private:create(LimiterCfg)]
20✔
62
        end,
63
    Limiters =
33,570✔
64
        case emqx_limiter_manager:find_bucket(Zone, Name) of
65
            {ok, Ref} ->
66
                [emqx_limiter_shared:create(Ref) | Private];
14✔
67
            undefined ->
68
                Private
33,556✔
69
        end,
70
    do_create_by_names(Names, Cfg, Zone, [{Name, Limiters} | Acc]);
33,570✔
71
do_create_by_names([], _Cfg, _Zone, Acc) ->
72
    create(Acc).
18,054✔
73

74
do_create([{Name, Limiters} | Groups], Seq, Acc) ->
75
    do_assign_limiters(Limiters, Name, Groups, Seq, [], Acc);
33,570✔
76
do_create([], 1, _Acc) ->
77
    undefined;
18,030✔
78
do_create([], _Seq, Acc) ->
79
    Acc.
24✔
80

81
do_assign_limiters([Limiter | Limiters], Name, Groups, Seq, Indexes, Acc) ->
82
    do_assign_limiters(Limiters, Name, Groups, Seq + 1, [Seq | Indexes], Acc#{Seq => Limiter});
34✔
83
do_assign_limiters([], Name, Groups, Seq, Indexes, Acc) ->
84
    do_create(Groups, Seq, Acc#{Name => Indexes}).
33,570✔
85

86
do_check([{Name, Need} | Needs], Container, Acc) ->
87
    case maps:find(Name, Container) of
70✔
88
        error ->
NEW
89
            do_check(Needs, Container, Acc);
×
90
        {ok, Indexes} ->
91
            case do_check_limiters(Need, Indexes, Container, Acc) of
70✔
92
                {true, Container2, Acc2} ->
93
                    do_check(Needs, Container2, Acc2);
50✔
94
                {false, Container2, Acc2} ->
95
                    {false, do_restore(Acc2, Container2)}
20✔
96
            end
97
    end;
98
do_check([], Container, _Acc) ->
99
    {true, Container}.
20✔
100

101
do_check_limiters(Need, [Index | Indexes], Container, Acc) ->
102
    Limiter = maps:get(Index, Container),
44✔
103
    case emqx_limiter:check(Need, Limiter) of
44✔
104
        {true, Limiter2} ->
105
            do_check_limiters(
24✔
106
                Need,
107
                Indexes,
108
                Container#{Index := Limiter2},
109
                [{Index, Need} | Acc]
110
            );
111
        {false, Limiter2} ->
112
            {false, Container#{Index := Limiter2}, Acc}
20✔
113
    end;
114
do_check_limiters(_, [], Container, Acc) ->
115
    {true, Container, Acc}.
50✔
116

117
do_restore([{Index, Consumed} | Indexes], Container) ->
NEW
118
    Limiter = maps:get(Index, Container),
×
NEW
119
    Limiter2 = emqx_limiter:restore(Consumed, Limiter),
×
NEW
120
    do_restore(Indexes, Container#{Index := Limiter2});
×
121
do_restore([], Container) ->
122
    Container.
20✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc