chore(emqx_retainer): change config of emqx_retainer to use hocon
This commit is contained in:
parent
e0f1087490
commit
860aea50db
|
@ -64,6 +64,7 @@ includes() ->[].
|
||||||
includes() ->
|
includes() ->
|
||||||
[ "emqx_data_bridge"
|
[ "emqx_data_bridge"
|
||||||
, "emqx_telemetry"
|
, "emqx_telemetry"
|
||||||
|
, "emqx_retainer"
|
||||||
].
|
].
|
||||||
-endif.
|
-endif.
|
||||||
|
|
||||||
|
|
|
@ -5,37 +5,39 @@
|
||||||
## Where to store the retained messages.
|
## Where to store the retained messages.
|
||||||
##
|
##
|
||||||
## Notice that all nodes in the same cluster have to be configured to
|
## Notice that all nodes in the same cluster have to be configured to
|
||||||
## use the same storage_type.
|
emqx_retainer: {
|
||||||
##
|
## use the same storage_type.
|
||||||
## Value: ram | disc | disc_only
|
##
|
||||||
## - ram: memory only
|
## Value: ram | disc | disc_only
|
||||||
## - disc: both memory and disc
|
## - ram: memory only
|
||||||
## - disc_only: disc only
|
## - disc: both memory and disc
|
||||||
##
|
## - disc_only: disc only
|
||||||
## Default: ram
|
##
|
||||||
retainer.storage_type = ram
|
## Default: ram
|
||||||
|
storage_type: ram
|
||||||
|
|
||||||
## Maximum number of retained messages. 0 means no limit.
|
## Maximum number of retained messages. 0 means no limit.
|
||||||
##
|
##
|
||||||
## Value: Number >= 0
|
## Value: Number >= 0
|
||||||
retainer.max_retained_messages = 0
|
max_retained_messages: 0
|
||||||
|
|
||||||
## Maximum retained message size.
|
## Maximum retained message size.
|
||||||
##
|
##
|
||||||
## Value: Bytes
|
## Value: Bytes
|
||||||
retainer.max_payload_size = 1MB
|
max_payload_size: 1MB
|
||||||
|
|
||||||
## Expiry interval of the retained messages. Never expire if the value is 0.
|
## Expiry interval of the retained messages. Never expire if the value is 0.
|
||||||
##
|
##
|
||||||
## Value: Duration
|
## Value: Duration
|
||||||
## - h: hour
|
## - h: hour
|
||||||
## - m: minute
|
## - m: minute
|
||||||
## - s: second
|
## - s: second
|
||||||
##
|
##
|
||||||
## Examples:
|
## Examples:
|
||||||
## - 2h: 2 hours
|
## - 2h: 2 hours
|
||||||
## - 30m: 30 minutes
|
## - 30m: 30 minutes
|
||||||
## - 20s: 20 seconds
|
## - 20s: 20 seconds
|
||||||
##
|
##
|
||||||
## Default: 0
|
## Default: 0s
|
||||||
retainer.expiry_interval = 0
|
expiry_interval: 0s
|
||||||
|
}
|
||||||
|
|
|
@ -1,30 +0,0 @@
|
||||||
%%-*- mode: erlang -*-
|
|
||||||
%% Retainer config mapping
|
|
||||||
|
|
||||||
%% Storage Type
|
|
||||||
%% {$configurable}
|
|
||||||
{mapping, "retainer.storage_type", "emqx_retainer.storage_type", [
|
|
||||||
{default, ram},
|
|
||||||
{datatype, {enum, [ram, disc, disc_only]}}
|
|
||||||
]}.
|
|
||||||
|
|
||||||
%% Maximum number of retained messages.
|
|
||||||
%% {$configurable}
|
|
||||||
{mapping, "retainer.max_retained_messages", "emqx_retainer.max_retained_messages", [
|
|
||||||
{default, 0},
|
|
||||||
{datatype, integer}
|
|
||||||
]}.
|
|
||||||
|
|
||||||
%% Maximum payload size of retained message.
|
|
||||||
%% {$configurable}
|
|
||||||
{mapping, "retainer.max_payload_size", "emqx_retainer.max_payload_size", [
|
|
||||||
{default, "1MB"},
|
|
||||||
{datatype, bytesize}
|
|
||||||
]}.
|
|
||||||
|
|
||||||
%% Expiry interval of retained message
|
|
||||||
%% {$configurable}
|
|
||||||
{mapping, "retainer.expiry_interval", "emqx_retainer.expiry_interval", [
|
|
||||||
{default, 0},
|
|
||||||
{datatype, [integer, {duration, ms}]}
|
|
||||||
]}.
|
|
|
@ -25,14 +25,14 @@
|
||||||
|
|
||||||
-logger_header("[Retainer]").
|
-logger_header("[Retainer]").
|
||||||
|
|
||||||
-export([start_link/1]).
|
-export([start_link/0]).
|
||||||
|
|
||||||
-export([ load/1
|
-export([ load/0
|
||||||
, unload/0
|
, unload/0
|
||||||
]).
|
]).
|
||||||
|
|
||||||
-export([ on_session_subscribed/3
|
-export([ on_session_subscribed/3
|
||||||
, on_message_publish/2
|
, on_message_publish/1
|
||||||
]).
|
]).
|
||||||
|
|
||||||
-export([clean/1]).
|
-export([clean/1]).
|
||||||
|
@ -51,15 +51,25 @@
|
||||||
|
|
||||||
-record(state, {stats_fun, stats_timer, expiry_timer}).
|
-record(state, {stats_fun, stats_timer, expiry_timer}).
|
||||||
|
|
||||||
|
-define(STATS_INTERVAL, timer:seconds(1)).
|
||||||
|
-define(DEF_STORAGE_TYPE, ram).
|
||||||
|
-define(DEF_MAX_RETAINED_MESSAGES, 0).
|
||||||
|
-define(DEF_MAX_PAYLOAD_SIZE, (1024 * 1024)).
|
||||||
|
-define(DEF_EXPIRY_INTERVAL, 0).
|
||||||
|
|
||||||
|
%% convenient to generate stats_timer/expiry_timer
|
||||||
|
-define(MAKE_TIMER(State, Timer, Interval, Msg),
|
||||||
|
State#state{Timer = erlang:send_after(Interval, self(), Msg)}).
|
||||||
|
|
||||||
-rlog_shard({?RETAINER_SHARD, ?TAB}).
|
-rlog_shard({?RETAINER_SHARD, ?TAB}).
|
||||||
|
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
%% Load/Unload
|
%% Load/Unload
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
|
|
||||||
load(Env) ->
|
load() ->
|
||||||
_ = emqx:hook('session.subscribed', {?MODULE, on_session_subscribed, []}),
|
_ = emqx:hook('session.subscribed', {?MODULE, on_session_subscribed, []}),
|
||||||
_ = emqx:hook('message.publish', {?MODULE, on_message_publish, [Env]}),
|
_ = emqx:hook('message.publish', {?MODULE, on_message_publish, []}),
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
unload() ->
|
unload() ->
|
||||||
|
@ -85,15 +95,15 @@ dispatch(Pid, Topic) ->
|
||||||
%% RETAIN flag set to 1 and payload containing zero bytes
|
%% RETAIN flag set to 1 and payload containing zero bytes
|
||||||
on_message_publish(Msg = #message{flags = #{retain := true},
|
on_message_publish(Msg = #message{flags = #{retain := true},
|
||||||
topic = Topic,
|
topic = Topic,
|
||||||
payload = <<>>}, _Env) ->
|
payload = <<>>}) ->
|
||||||
ekka_mnesia:dirty_delete(?TAB, topic2tokens(Topic)),
|
ekka_mnesia:dirty_delete(?TAB, topic2tokens(Topic)),
|
||||||
{ok, Msg};
|
{ok, Msg};
|
||||||
|
|
||||||
on_message_publish(Msg = #message{flags = #{retain := true}}, Env) ->
|
on_message_publish(Msg = #message{flags = #{retain := true}}) ->
|
||||||
Msg1 = emqx_message:set_header(retained, true, Msg),
|
Msg1 = emqx_message:set_header(retained, true, Msg),
|
||||||
store_retained(Msg1, Env),
|
store_retained(Msg1),
|
||||||
{ok, Msg};
|
{ok, Msg};
|
||||||
on_message_publish(Msg, _Env) ->
|
on_message_publish(Msg) ->
|
||||||
{ok, Msg}.
|
{ok, Msg}.
|
||||||
|
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
|
@ -101,9 +111,9 @@ on_message_publish(Msg, _Env) ->
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
|
|
||||||
%% @doc Start the retainer
|
%% @doc Start the retainer
|
||||||
-spec(start_link(Env :: list()) -> emqx_types:startlink_ret()).
|
-spec(start_link() -> emqx_types:startlink_ret()).
|
||||||
start_link(Env) ->
|
start_link() ->
|
||||||
gen_server:start_link({local, ?MODULE}, ?MODULE, [Env], []).
|
gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
|
||||||
|
|
||||||
-spec(clean(emqx_types:topic()) -> non_neg_integer()).
|
-spec(clean(emqx_types:topic()) -> non_neg_integer()).
|
||||||
clean(Topic) when is_binary(Topic) ->
|
clean(Topic) when is_binary(Topic) ->
|
||||||
|
@ -124,8 +134,10 @@ clean(Topic) when is_binary(Topic) ->
|
||||||
%% gen_server callbacks
|
%% gen_server callbacks
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
|
|
||||||
init([Env]) ->
|
init([]) ->
|
||||||
Copies = case proplists:get_value(storage_type, Env, disc) of
|
StorageType = emqx_config:get([?MODULE, storage_type], ?DEF_STORAGE_TYPE),
|
||||||
|
ExpiryInterval = emqx_config:get([?MODULE, expiry_interval], ?DEF_EXPIRY_INTERVAL),
|
||||||
|
Copies = case StorageType of
|
||||||
ram -> ram_copies;
|
ram -> ram_copies;
|
||||||
disc -> disc_copies;
|
disc -> disc_copies;
|
||||||
disc_only -> disc_only_copies
|
disc_only -> disc_only_copies
|
||||||
|
@ -149,17 +161,15 @@ init([Env]) ->
|
||||||
ok
|
ok
|
||||||
end,
|
end,
|
||||||
StatsFun = emqx_stats:statsfun('retained.count', 'retained.max'),
|
StatsFun = emqx_stats:statsfun('retained.count', 'retained.max'),
|
||||||
{ok, StatsTimer} = timer:send_interval(timer:seconds(1), stats),
|
State = ?MAKE_TIMER(#state{stats_fun = StatsFun}, stats_timer, ?STATS_INTERVAL, stats),
|
||||||
State = #state{stats_fun = StatsFun, stats_timer = StatsTimer},
|
{ok, start_expire_timer(ExpiryInterval, State)}.
|
||||||
{ok, start_expire_timer(proplists:get_value(expiry_interval, Env, 0), State)}.
|
|
||||||
|
|
||||||
start_expire_timer(0, State) ->
|
start_expire_timer(0, State) ->
|
||||||
State;
|
State;
|
||||||
start_expire_timer(undefined, State) ->
|
start_expire_timer(undefined, State) ->
|
||||||
State;
|
State;
|
||||||
start_expire_timer(Ms, State) ->
|
start_expire_timer(Ms, State) ->
|
||||||
{ok, Timer} = timer:send_interval(Ms, expire),
|
?MAKE_TIMER(State, expiry_timer, Ms, expire).
|
||||||
State#state{expiry_timer = Timer}.
|
|
||||||
|
|
||||||
handle_call(Req, _From, State) ->
|
handle_call(Req, _From, State) ->
|
||||||
?LOG(error, "Unexpected call: ~p", [Req]),
|
?LOG(error, "Unexpected call: ~p", [Req]),
|
||||||
|
@ -171,19 +181,20 @@ handle_cast(Msg, State) ->
|
||||||
|
|
||||||
handle_info(stats, State = #state{stats_fun = StatsFun}) ->
|
handle_info(stats, State = #state{stats_fun = StatsFun}) ->
|
||||||
StatsFun(retained_count()),
|
StatsFun(retained_count()),
|
||||||
{noreply, State, hibernate};
|
{noreply, ?MAKE_TIMER(State, stats_timer, ?STATS_INTERVAL, stats), hibernate};
|
||||||
|
|
||||||
handle_info(expire, State) ->
|
handle_info(expire, State) ->
|
||||||
ok = expire_messages(),
|
ok = expire_messages(),
|
||||||
{noreply, State, hibernate};
|
Interval = emqx_config:get([?MODULE, expiry_interval], ?DEF_EXPIRY_INTERVAL),
|
||||||
|
{noreply, start_expire_timer(Interval, State), hibernate};
|
||||||
|
|
||||||
handle_info(Info, State) ->
|
handle_info(Info, State) ->
|
||||||
?LOG(error, "Unexpected info: ~p", [Info]),
|
?LOG(error, "Unexpected info: ~p", [Info]),
|
||||||
{noreply, State}.
|
{noreply, State}.
|
||||||
|
|
||||||
terminate(_Reason, #state{stats_timer = TRef1, expiry_timer = TRef2}) ->
|
terminate(_Reason, #state{stats_timer = TRef1, expiry_timer = TRef2}) ->
|
||||||
_ = timer:cancel(TRef1),
|
_ = erlang:cancel_timer(TRef1),
|
||||||
_ = timer:cancel(TRef2),
|
_ = erlang:cancel_timer(TRef2),
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
code_change(_OldVsn, State, _Extra) ->
|
code_change(_OldVsn, State, _Extra) ->
|
||||||
|
@ -192,31 +203,33 @@ code_change(_OldVsn, State, _Extra) ->
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
%% Internal functions
|
%% Internal functions
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
|
|
||||||
sort_retained([]) -> [];
|
sort_retained([]) -> [];
|
||||||
sort_retained([Msg]) -> [Msg];
|
sort_retained([Msg]) -> [Msg];
|
||||||
sort_retained(Msgs) ->
|
sort_retained(Msgs) ->
|
||||||
lists:sort(fun(#message{timestamp = Ts1}, #message{timestamp = Ts2}) ->
|
lists:sort(fun(#message{timestamp = Ts1}, #message{timestamp = Ts2}) ->
|
||||||
Ts1 =< Ts2
|
Ts1 =< Ts2 end,
|
||||||
end, Msgs).
|
Msgs).
|
||||||
|
|
||||||
store_retained(Msg = #message{topic = Topic, payload = Payload}, Env) ->
|
store_retained(Msg = #message{topic = Topic, payload = Payload}) ->
|
||||||
case {is_table_full(Env), is_too_big(size(Payload), Env)} of
|
case {is_table_full(), is_too_big(size(Payload))} of
|
||||||
{false, false} ->
|
{false, false} ->
|
||||||
ok = emqx_metrics:inc('messages.retained'),
|
ok = emqx_metrics:inc('messages.retained'),
|
||||||
ekka_mnesia:dirty_write(?TAB, #retained{topic = topic2tokens(Topic),
|
ekka_mnesia:dirty_write(?TAB, #retained{topic = topic2tokens(Topic),
|
||||||
msg = Msg,
|
msg = Msg,
|
||||||
expiry_time = get_expiry_time(Msg, Env)});
|
expiry_time = get_expiry_time(Msg)});
|
||||||
{true, false} ->
|
{true, false} ->
|
||||||
{atomic, _} = ekka_mnesia:transaction(?RETAINER_SHARD,
|
{atomic, _} = ekka_mnesia:transaction(?RETAINER_SHARD,
|
||||||
fun() ->
|
fun() ->
|
||||||
case mnesia:read(?TAB, Topic) of
|
case mnesia:read(?TAB, Topic) of
|
||||||
[_] ->
|
[_] ->
|
||||||
mnesia:write(?TAB, #retained{topic = topic2tokens(Topic),
|
mnesia:write(?TAB,
|
||||||
msg = Msg,
|
#retained{topic = topic2tokens(Topic),
|
||||||
expiry_time = get_expiry_time(Msg, Env)}, write);
|
msg = Msg,
|
||||||
[] ->
|
expiry_time = get_expiry_time(Msg)},
|
||||||
?LOG(error, "Cannot retain message(topic=~s) for table is full!", [Topic])
|
write);
|
||||||
|
[] ->
|
||||||
|
?LOG(error,
|
||||||
|
"Cannot retain message(topic=~s) for table is full!", [Topic])
|
||||||
end
|
end
|
||||||
end),
|
end),
|
||||||
ok;
|
ok;
|
||||||
|
@ -227,22 +240,24 @@ store_retained(Msg = #message{topic = Topic, payload = Payload}, Env) ->
|
||||||
"for payload is too big!", [Topic, iolist_size(Payload)])
|
"for payload is too big!", [Topic, iolist_size(Payload)])
|
||||||
end.
|
end.
|
||||||
|
|
||||||
is_table_full(Env) ->
|
is_table_full() ->
|
||||||
Limit = proplists:get_value(max_retained_messages, Env, 0),
|
Limit = emqx_config:get([?MODULE, max_retained_messages], ?DEF_MAX_RETAINED_MESSAGES),
|
||||||
Limit > 0 andalso (retained_count() > Limit).
|
Limit > 0 andalso (retained_count() > Limit).
|
||||||
|
|
||||||
is_too_big(Size, Env) ->
|
is_too_big(Size) ->
|
||||||
Limit = proplists:get_value(max_payload_size, Env, 0),
|
Limit = emqx_config:get([?MODULE, max_payload_size], ?DEF_MAX_PAYLOAD_SIZE),
|
||||||
Limit > 0 andalso (Size > Limit).
|
Limit > 0 andalso (Size > Limit).
|
||||||
|
|
||||||
get_expiry_time(#message{headers = #{properties := #{'Message-Expiry-Interval' := 0}}}, _Env) ->
|
get_expiry_time(#message{headers = #{properties := #{'Message-Expiry-Interval' := 0}}}) ->
|
||||||
0;
|
0;
|
||||||
get_expiry_time(#message{headers = #{properties := #{'Message-Expiry-Interval' := Interval}}, timestamp = Ts}, _Env) ->
|
get_expiry_time(#message{headers = #{properties := #{'Message-Expiry-Interval' := Interval}},
|
||||||
|
timestamp = Ts}) ->
|
||||||
Ts + Interval * 1000;
|
Ts + Interval * 1000;
|
||||||
get_expiry_time(#message{timestamp = Ts}, Env) ->
|
get_expiry_time(#message{timestamp = Ts}) ->
|
||||||
case proplists:get_value(expiry_interval, Env, 0) of
|
Interval = emqx_config:get([?MODULE, expiry_interval], ?DEF_EXPIRY_INTERVAL),
|
||||||
|
case Interval of
|
||||||
0 -> 0;
|
0 -> 0;
|
||||||
Interval -> Ts + Interval
|
_ -> Ts + Interval
|
||||||
end.
|
end.
|
||||||
|
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
|
|
|
@ -25,9 +25,8 @@
|
||||||
]).
|
]).
|
||||||
|
|
||||||
start(_Type, _Args) ->
|
start(_Type, _Args) ->
|
||||||
Env = application:get_all_env(emqx_retainer),
|
{ok, Sup} = emqx_retainer_sup:start_link(),
|
||||||
{ok, Sup} = emqx_retainer_sup:start_link(Env),
|
emqx_retainer:load(),
|
||||||
emqx_retainer:load(Env),
|
|
||||||
emqx_retainer_cli:load(),
|
emqx_retainer_cli:load(),
|
||||||
{ok, Sup}.
|
{ok, Sup}.
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
-module(emqx_retainer_schema).
|
||||||
|
|
||||||
|
-include_lib("typerefl/include/types.hrl").
|
||||||
|
|
||||||
|
-type storage_type() :: ram | disc | disc_only.
|
||||||
|
|
||||||
|
-reflect_type([storage_type/0]).
|
||||||
|
|
||||||
|
-export([structs/0, fields/1]).
|
||||||
|
|
||||||
|
structs() -> ["emqx_retainer"].
|
||||||
|
|
||||||
|
fields("emqx_retainer") ->
|
||||||
|
[ {storage_type, t(storage_type(), ram)}
|
||||||
|
, {max_retained_messages, t(integer(), 0, fun is_pos_integer/1)}
|
||||||
|
, {max_payload_size, t(emqx_schema:bytesize(), "1MB")}
|
||||||
|
, {expiry_interval, t(emqx_schema:duration_ms(), "0s")}
|
||||||
|
].
|
||||||
|
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
%% Internal functions
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
t(Type, Default) ->
|
||||||
|
hoconsc:t(Type, #{default => Default}).
|
||||||
|
|
||||||
|
t(Type, Default, Validator) ->
|
||||||
|
hoconsc:t(Type, #{default => Default,
|
||||||
|
validator => Validator}).
|
||||||
|
|
||||||
|
is_pos_integer(V) ->
|
||||||
|
V >= 0.
|
|
@ -18,17 +18,17 @@
|
||||||
|
|
||||||
-behaviour(supervisor).
|
-behaviour(supervisor).
|
||||||
|
|
||||||
-export([start_link/1]).
|
-export([start_link/0]).
|
||||||
|
|
||||||
-export([init/1]).
|
-export([init/1]).
|
||||||
|
|
||||||
start_link(Env) ->
|
start_link() ->
|
||||||
supervisor:start_link({local, ?MODULE}, ?MODULE, [Env]).
|
supervisor:start_link({local, ?MODULE}, ?MODULE, []).
|
||||||
|
|
||||||
init([Env]) ->
|
init([]) ->
|
||||||
{ok, {{one_for_one, 10, 3600},
|
{ok, {{one_for_one, 10, 3600},
|
||||||
[#{id => retainer,
|
[#{id => retainer,
|
||||||
start => {emqx_retainer, start_link, [Env]},
|
start => {emqx_retainer, start_link, []},
|
||||||
restart => permanent,
|
restart => permanent,
|
||||||
shutdown => 5000,
|
shutdown => 5000,
|
||||||
type => worker,
|
type => worker,
|
||||||
|
|
|
@ -31,7 +31,7 @@ all() -> emqx_ct:all(?MODULE).
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
|
|
||||||
init_per_suite(Config) ->
|
init_per_suite(Config) ->
|
||||||
emqx_ct_helpers:start_apps([emqx_retainer]),
|
emqx_ct_helpers:start_apps([emqx_retainer], fun set_special_configs/1),
|
||||||
Config.
|
Config.
|
||||||
|
|
||||||
end_per_suite(_Config) ->
|
end_per_suite(_Config) ->
|
||||||
|
@ -39,16 +39,26 @@ end_per_suite(_Config) ->
|
||||||
|
|
||||||
init_per_testcase(TestCase, Config) ->
|
init_per_testcase(TestCase, Config) ->
|
||||||
emqx_retainer:clean(<<"#">>),
|
emqx_retainer:clean(<<"#">>),
|
||||||
case TestCase of
|
Interval = case TestCase of
|
||||||
t_message_expiry_2 ->
|
t_message_expiry_2 -> 2000;
|
||||||
application:set_env(emqx_retainer, expiry_interval, 2000);
|
_ -> 0
|
||||||
_ ->
|
end,
|
||||||
application:set_env(emqx_retainer, expiry_interval, 0)
|
init_emqx_retainer_conf(Interval),
|
||||||
end,
|
|
||||||
application:stop(emqx_retainer),
|
|
||||||
application:ensure_all_started(emqx_retainer),
|
application:ensure_all_started(emqx_retainer),
|
||||||
Config.
|
Config.
|
||||||
|
|
||||||
|
set_special_configs(emqx_retainer) ->
|
||||||
|
init_emqx_retainer_conf(0);
|
||||||
|
set_special_configs(_) ->
|
||||||
|
ok.
|
||||||
|
|
||||||
|
init_emqx_retainer_conf(Expiry) ->
|
||||||
|
emqx_config:put([emqx_retainer],
|
||||||
|
#{storage_type => ram,
|
||||||
|
max_retained_messages => 0,
|
||||||
|
max_payload_size => 1024 * 1024,
|
||||||
|
expiry_interval => Expiry}).
|
||||||
|
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
%% Test Cases
|
%% Test Cases
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
|
|
Loading…
Reference in New Issue