retained_message -> mqtt_retained
This commit is contained in:
parent
5eda6c9dd2
commit
edb45d7029
|
@ -7,9 +7,40 @@ Changes
|
||||||
|
|
||||||
.. _release_2.0:
|
.. _release_2.0:
|
||||||
|
|
||||||
-------------------------------------
|
-------------------------------
|
||||||
Version 2.0-beta1 (West of West Lake)
|
Version 2.0 (West of West Lake)
|
||||||
-------------------------------------
|
-------------------------------
|
||||||
|
|
||||||
|
*Release Date: 2016-09-30*
|
||||||
|
|
||||||
|
*Release Name: West of West Lake*
|
||||||
|
|
||||||
|
TODO: ...
|
||||||
|
|
||||||
|
-----------------
|
||||||
|
Version 2.0-beta2
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
*Release Date: 2016-09-10*
|
||||||
|
|
||||||
|
API Breaking Changes
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
'$u', '$c' variables in emqttd.conf and modules/acl.conf changed to '%u', '%c'
|
||||||
|
|
||||||
|
Improve the design of mqtt retained message, replace emqttd_retainer with emqttd_mod_retainer.
|
||||||
|
|
||||||
|
Add 'session.subscribed', 'session.unsubscribed' hooks, remove 'client.subscribe.after' hook
|
||||||
|
|
||||||
|
Tab 'retained_message' -> 'mqtt_retained'
|
||||||
|
|
||||||
|
Bugfix
|
||||||
|
------
|
||||||
|
|
||||||
|
|
||||||
|
-----------------
|
||||||
|
Version 2.0-beta1
|
||||||
|
-----------------
|
||||||
|
|
||||||
*Release Date: 2016-08-30*
|
*Release Date: 2016-08-30*
|
||||||
|
|
||||||
|
|
|
@ -39,7 +39,7 @@
|
||||||
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
|
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
|
||||||
terminate/2, code_change/3]).
|
terminate/2, code_change/3]).
|
||||||
|
|
||||||
-record(retained_message, {topic, msg}).
|
-record(mqtt_retained, {topic, msg}).
|
||||||
|
|
||||||
-record(state, {stats_fun, expired_after, stats_timer, expire_timer}).
|
-record(state, {stats_fun, expired_after, stats_timer, expire_timer}).
|
||||||
|
|
||||||
|
@ -65,13 +65,13 @@ on_message_publish(Msg = #mqtt_message{retain = false}, _Env) ->
|
||||||
|
|
||||||
%% RETAIN flag set to 1 and payload containing zero bytes
|
%% RETAIN flag set to 1 and payload containing zero bytes
|
||||||
on_message_publish(Msg = #mqtt_message{retain = true, topic = Topic, payload = <<>>}, _Env) ->
|
on_message_publish(Msg = #mqtt_message{retain = true, topic = Topic, payload = <<>>}, _Env) ->
|
||||||
mnesia:dirty_delete(retained_message, Topic),
|
mnesia:dirty_delete(mqtt_retained, Topic),
|
||||||
{stop, Msg};
|
{stop, Msg};
|
||||||
|
|
||||||
on_message_publish(Msg = #mqtt_message{topic = Topic, retain = true, payload = Payload}, Env) ->
|
on_message_publish(Msg = #mqtt_message{topic = Topic, retain = true, payload = Payload}, Env) ->
|
||||||
case {is_table_full(Env), is_too_big(size(Payload), Env)} of
|
case {is_table_full(Env), is_too_big(size(Payload), Env)} of
|
||||||
{false, false} ->
|
{false, false} ->
|
||||||
mnesia:dirty_write(#retained_message{topic = Topic, msg = Msg}),
|
mnesia:dirty_write(#mqtt_retained{topic = Topic, msg = Msg}),
|
||||||
emqttd_metrics:set('messages/retained', retained_count());
|
emqttd_metrics:set('messages/retained', retained_count());
|
||||||
{true, _}->
|
{true, _}->
|
||||||
lager:error("Cannot retain message(topic=~s) for table is full!", [Topic]);
|
lager:error("Cannot retain message(topic=~s) for table is full!", [Topic]);
|
||||||
|
@ -111,20 +111,19 @@ start_link(Env) ->
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
|
|
||||||
init([Env]) ->
|
init([Env]) ->
|
||||||
Copy = case proplists:get_value(storage, Env, disc) of
|
Copy = case proplists:get_value(storage_type, Env, disc) of
|
||||||
disc -> disc_copies;
|
disc -> disc_copies;
|
||||||
ram -> ram_copies
|
ram -> ram_copies
|
||||||
end,
|
end,
|
||||||
ok = emqttd_mnesia:create_table(retained_message, [
|
ok = emqttd_mnesia:create_table(mqtt_retained, [
|
||||||
{type, ordered_set},
|
{type, ordered_set},
|
||||||
{Copy, [node()]},
|
{Copy, [node()]},
|
||||||
{record_name, retained_message},
|
{record_name, mqtt_retained},
|
||||||
{attributes, record_info(fields, retained_message)},
|
{attributes, record_info(fields, mqtt_retained)},
|
||||||
{storage_properties, [{ets, [compressed]},
|
{storage_properties, [{ets, [compressed]},
|
||||||
{dets, [{auto_save, 1000}]}]}]),
|
{dets, [{auto_save, 1000}]}]}]),
|
||||||
ok = emqttd_mnesia:copy_table(retained_message),
|
ok = emqttd_mnesia:copy_table(mqtt_retained),
|
||||||
StatsFun = emqttd_stats:statsfun('retained/count', 'retained/max'),
|
StatsFun = emqttd_stats:statsfun('retained/count', 'retained/max'),
|
||||||
%% One second
|
|
||||||
{ok, StatsTimer} = timer:send_interval(timer:seconds(1), stats),
|
{ok, StatsTimer} = timer:send_interval(timer:seconds(1), stats),
|
||||||
State = #state{stats_fun = StatsFun, stats_timer = StatsTimer},
|
State = #state{stats_fun = StatsFun, stats_timer = StatsTimer},
|
||||||
{ok, init_expire_timer(proplists:get_value(expired_after, Env, 0), State)}.
|
{ok, init_expire_timer(proplists:get_value(expired_after, Env, 0), State)}.
|
||||||
|
@ -171,33 +170,33 @@ code_change(_OldVsn, State, _Extra) ->
|
||||||
|
|
||||||
-spec(read_messages(binary()) -> [mqtt_message()]).
|
-spec(read_messages(binary()) -> [mqtt_message()]).
|
||||||
read_messages(Topic) ->
|
read_messages(Topic) ->
|
||||||
[Msg || #retained_message{msg = Msg} <- mnesia:dirty_read(retained_message, Topic)].
|
[Msg || #mqtt_retained{msg = Msg} <- mnesia:dirty_read(mqtt_retained, Topic)].
|
||||||
|
|
||||||
-spec(match_messages(binary()) -> [mqtt_message()]).
|
-spec(match_messages(binary()) -> [mqtt_message()]).
|
||||||
match_messages(Filter) ->
|
match_messages(Filter) ->
|
||||||
%% TODO: optimize later...
|
%% TODO: optimize later...
|
||||||
Fun = fun(#retained_message{topic = Name, msg = Msg}, Acc) ->
|
Fun = fun(#mqtt_retained{topic = Name, msg = Msg}, Acc) ->
|
||||||
case emqttd_topic:match(Name, Filter) of
|
case emqttd_topic:match(Name, Filter) of
|
||||||
true -> [Msg|Acc];
|
true -> [Msg|Acc];
|
||||||
false -> Acc
|
false -> Acc
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
mnesia:async_dirty(fun mnesia:foldl/3, [Fun, [], retained_message]).
|
mnesia:async_dirty(fun mnesia:foldl/3, [Fun, [], mqtt_retained]).
|
||||||
|
|
||||||
-spec(expire_messages(pos_integer()) -> any()).
|
-spec(expire_messages(pos_integer()) -> any()).
|
||||||
expire_messages(Time) when is_integer(Time) ->
|
expire_messages(Time) when is_integer(Time) ->
|
||||||
mnesia:transaction(
|
mnesia:transaction(
|
||||||
fun() ->
|
fun() ->
|
||||||
Match = ets:fun2ms(
|
Match = ets:fun2ms(
|
||||||
fun(#retained_message{topic = Topic, msg = #mqtt_message{timestamp = Ts}})
|
fun(#mqtt_retained{topic = Topic, msg = #mqtt_message{timestamp = Ts}})
|
||||||
when Time > Ts -> Topic
|
when Time > Ts -> Topic
|
||||||
end),
|
end),
|
||||||
Topics = mnesia:select(retained_message, Match, write),
|
Topics = mnesia:select(mqtt_retained, Match, write),
|
||||||
lists:foreach(fun(<<"$SYS/", _/binary>>) -> ok; %% ignore $SYS/# messages
|
lists:foreach(fun(<<"$SYS/", _/binary>>) -> ok; %% ignore $SYS/# messages
|
||||||
(Topic) -> mnesia:delete({retained_message, Topic})
|
(Topic) -> mnesia:delete({mqtt_retained, Topic})
|
||||||
end, Topics)
|
end, Topics)
|
||||||
end).
|
end).
|
||||||
|
|
||||||
-spec(retained_count() -> non_neg_integer()).
|
-spec(retained_count() -> non_neg_integer()).
|
||||||
retained_count() -> mnesia:table_info(retained_message, size).
|
retained_count() -> mnesia:table_info(mqtt_retained, size).
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue