chore(mqueue): Implement live upgrade
This commit is contained in:
parent
ed61999fdf
commit
5fc1036cf7
|
@ -67,6 +67,9 @@
|
||||||
, dropped/1
|
, dropped/1
|
||||||
]).
|
]).
|
||||||
|
|
||||||
|
-export([ live_upgrade/1
|
||||||
|
]).
|
||||||
|
|
||||||
-export_type([mqueue/0, options/0]).
|
-export_type([mqueue/0, options/0]).
|
||||||
|
|
||||||
-type(topic() :: emqx_topic:topic()).
|
-type(topic() :: emqx_topic:topic()).
|
||||||
|
@ -111,6 +114,8 @@
|
||||||
|
|
||||||
-type(mqueue() :: #mqueue{}).
|
-type(mqueue() :: #mqueue{}).
|
||||||
|
|
||||||
|
-define(OLD(Q), Q = {mqueue, _, _, _, _, _, _, _}).
|
||||||
|
|
||||||
-spec(init(options()) -> mqueue()).
|
-spec(init(options()) -> mqueue()).
|
||||||
init(Opts = #{max_len := MaxLen0, store_qos0 := QoS_0}) ->
|
init(Opts = #{max_len := MaxLen0, store_qos0 := QoS_0}) ->
|
||||||
MaxLen = case (is_integer(MaxLen0) andalso MaxLen0 > ?MAX_LEN_INFINITY) of
|
MaxLen = case (is_integer(MaxLen0) andalso MaxLen0 > ?MAX_LEN_INFINITY) of
|
||||||
|
@ -136,22 +141,30 @@ info(max_len, #mqueue{max_len = MaxLen}) ->
|
||||||
info(len, #mqueue{len = Len}) ->
|
info(len, #mqueue{len = Len}) ->
|
||||||
Len;
|
Len;
|
||||||
info(dropped, #mqueue{dropped = Dropped}) ->
|
info(dropped, #mqueue{dropped = Dropped}) ->
|
||||||
Dropped.
|
Dropped;
|
||||||
|
info(Info, ?OLD(MQ)) ->
|
||||||
|
info(Info, live_upgrade(MQ)).
|
||||||
|
|
||||||
is_empty(#mqueue{len = Len}) -> Len =:= 0.
|
is_empty(#mqueue{len = Len}) -> Len =:= 0;
|
||||||
|
is_empty(?OLD(MQ)) -> is_empty(live_upgrade(MQ)).
|
||||||
|
|
||||||
len(#mqueue{len = Len}) -> Len.
|
len(#mqueue{len = Len}) -> Len;
|
||||||
|
len(?OLD(MQ)) -> len(live_upgrade(MQ)).
|
||||||
|
|
||||||
max_len(#mqueue{max_len = MaxLen}) -> MaxLen.
|
max_len(#mqueue{max_len = MaxLen}) -> MaxLen;
|
||||||
|
max_len(?OLD(MQ)) -> max_len(live_upgrade(MQ)).
|
||||||
|
|
||||||
%% @doc Return number of dropped messages.
|
%% @doc Return number of dropped messages.
|
||||||
-spec(dropped(mqueue()) -> count()).
|
-spec(dropped(mqueue()) -> count()).
|
||||||
dropped(#mqueue{dropped = Dropped}) -> Dropped.
|
dropped(#mqueue{dropped = Dropped}) -> Dropped;
|
||||||
|
dropped(?OLD(MQ)) -> dropped(live_upgrade(MQ)).
|
||||||
|
|
||||||
%% @doc Stats of the mqueue
|
%% @doc Stats of the mqueue
|
||||||
-spec(stats(mqueue()) -> [stat()]).
|
-spec(stats(mqueue()) -> [stat()]).
|
||||||
stats(#mqueue{max_len = MaxLen, dropped = Dropped} = MQ) ->
|
stats(#mqueue{max_len = MaxLen, dropped = Dropped} = MQ) ->
|
||||||
[{len, len(MQ)}, {max_len, MaxLen}, {dropped, Dropped}].
|
[{len, len(MQ)}, {max_len, MaxLen}, {dropped, Dropped}];
|
||||||
|
stats(?OLD(MQ)) ->
|
||||||
|
stats(live_upgrade(MQ)).
|
||||||
|
|
||||||
%% @doc Enqueue a message.
|
%% @doc Enqueue a message.
|
||||||
-spec(in(message(), mqueue()) -> {maybe(message()), mqueue()}).
|
-spec(in(message(), mqueue()) -> {maybe(message()), mqueue()}).
|
||||||
|
@ -174,7 +187,9 @@ in(Msg = #message{topic = Topic}, MQ = #mqueue{default_p = Dp,
|
||||||
{DroppedMsg, MQ#mqueue{q = Q2, dropped = Dropped + 1}};
|
{DroppedMsg, MQ#mqueue{q = Q2, dropped = Dropped + 1}};
|
||||||
false ->
|
false ->
|
||||||
{_DroppedMsg = undefined, MQ#mqueue{len = Len + 1, q = ?PQUEUE:in(Msg, Priority, Q)}}
|
{_DroppedMsg = undefined, MQ#mqueue{len = Len + 1, q = ?PQUEUE:in(Msg, Priority, Q)}}
|
||||||
end.
|
end;
|
||||||
|
in(Msg, ?OLD(MQ)) ->
|
||||||
|
in(Msg, live_upgrade(MQ)).
|
||||||
|
|
||||||
-spec(out(mqueue()) -> {empty | {value, message()}, mqueue()}).
|
-spec(out(mqueue()) -> {empty | {value, message()}, mqueue()}).
|
||||||
out(MQ = #mqueue{len = 0, q = Q}) ->
|
out(MQ = #mqueue{len = 0, q = Q}) ->
|
||||||
|
@ -198,7 +213,9 @@ out(MQ = #mqueue{q = Q, counter = 0}) ->
|
||||||
out(MQ = #mqueue{q = Q, len = Len, counter = Cnt}) ->
|
out(MQ = #mqueue{q = Q, len = Len, counter = Cnt}) ->
|
||||||
ct:pal("Cnt ~p", [Cnt]),
|
ct:pal("Cnt ~p", [Cnt]),
|
||||||
{R, Q1} = ?PQUEUE:out(Q),
|
{R, Q1} = ?PQUEUE:out(Q),
|
||||||
{R, MQ#mqueue{q = Q1, len = Len - 1, counter = Cnt - 1}}.
|
{R, MQ#mqueue{q = Q1, len = Len - 1, counter = Cnt - 1}};
|
||||||
|
out(?OLD(MQ)) ->
|
||||||
|
out(live_upgrade(MQ)).
|
||||||
|
|
||||||
get_opt(Key, Opts, Default) ->
|
get_opt(Key, Opts, Default) ->
|
||||||
case maps:get(Key, Opts, Default) of
|
case maps:get(Key, Opts, Default) of
|
||||||
|
@ -245,3 +262,20 @@ get_shift_opt(Opts) ->
|
||||||
multiplier = Mult,
|
multiplier = Mult,
|
||||||
base = Base
|
base = Base
|
||||||
}.
|
}.
|
||||||
|
|
||||||
|
live_upgrade({mqueue, StoreQos0, MaxLen, Len, Dropped, PTable, DefaultP, Q}) ->
|
||||||
|
ShiftOpts = case is_map(PTable) of
|
||||||
|
true -> get_shift_opt(#{p_table => PTable});
|
||||||
|
false -> get_shift_opt(#{})
|
||||||
|
end,
|
||||||
|
#mqueue{ store_qos0 = StoreQos0
|
||||||
|
, max_len = MaxLen
|
||||||
|
, dropped = Dropped
|
||||||
|
, p_table = PTable
|
||||||
|
, default_p = DefaultP
|
||||||
|
, len = Len
|
||||||
|
, q = Q
|
||||||
|
, shift_opts = ShiftOpts
|
||||||
|
, last_p = undefined
|
||||||
|
, counter = undefined
|
||||||
|
}.
|
||||||
|
|
|
@ -211,6 +211,33 @@ t_dropped(_) ->
|
||||||
{Msg, Q2} = ?Q:in(Msg, Q1),
|
{Msg, Q2} = ?Q:in(Msg, Q1),
|
||||||
?assertEqual(1, ?Q:dropped(Q2)).
|
?assertEqual(1, ?Q:dropped(Q2)).
|
||||||
|
|
||||||
|
t_live_upgrade(_) ->
|
||||||
|
Q = {mqueue,true,1,0,0,none,0,
|
||||||
|
{queue,[],[],0}},
|
||||||
|
?assertMatch(#{}, ?Q:info(Q)),
|
||||||
|
?assertMatch(true, ?Q:is_empty(Q)),
|
||||||
|
?assertMatch(0, ?Q:len(Q)),
|
||||||
|
?assertMatch(1, ?Q:max_len(Q)),
|
||||||
|
?assertMatch({undefined, _}, ?Q:in(#message{qos = 0, topic = <<>>}, Q)),
|
||||||
|
?assertMatch({empty, _}, ?Q:out(Q)),
|
||||||
|
?assertMatch([_|_], ?Q:stats(Q)),
|
||||||
|
?assertMatch(0, ?Q:dropped(Q)).
|
||||||
|
|
||||||
|
|
||||||
|
t_live_upgrade2(_) ->
|
||||||
|
Q = {mqueue,false,10,0,0,
|
||||||
|
#{<<"t">> => 1},
|
||||||
|
0,
|
||||||
|
{queue,[],[],0}},
|
||||||
|
?assertMatch(#{}, ?Q:info(Q)),
|
||||||
|
?assertMatch(true, ?Q:is_empty(Q)),
|
||||||
|
?assertMatch(0, ?Q:len(Q)),
|
||||||
|
?assertMatch(10, ?Q:max_len(Q)),
|
||||||
|
?assertMatch({_, _}, ?Q:in(#message{qos = 0, topic = <<>>}, Q)),
|
||||||
|
?assertMatch({empty, _}, ?Q:out(Q)),
|
||||||
|
?assertMatch([_|_], ?Q:stats(Q)),
|
||||||
|
?assertMatch(0, ?Q:dropped(Q)).
|
||||||
|
|
||||||
conservation_prop() ->
|
conservation_prop() ->
|
||||||
?FORALL({Priorities, Messages},
|
?FORALL({Priorities, Messages},
|
||||||
?LET(Priorities, topic_priorities(),
|
?LET(Priorities, topic_priorities(),
|
||||||
|
|
Loading…
Reference in New Issue