spec/1
This commit is contained in:
parent
0c13490092
commit
855152f653
|
@ -36,7 +36,7 @@
|
||||||
%% API Function Exports
|
%% API Function Exports
|
||||||
-export([start_link/2, session/1, info/1, kick/1]).
|
-export([start_link/2, session/1, info/1, kick/1]).
|
||||||
|
|
||||||
%% SUB/UNSUB Asynchronously, called by plugins.
|
%% SUB/UNSUB Asynchronously. Called by plugins.
|
||||||
-export([subscribe/2, unsubscribe/2]).
|
-export([subscribe/2, unsubscribe/2]).
|
||||||
|
|
||||||
%% gen_server Function Exports
|
%% gen_server Function Exports
|
||||||
|
@ -243,7 +243,7 @@ with_session(Fun, State = #client_state{proto_state = ProtoState}) ->
|
||||||
Fun(emqttd_protocol:session(ProtoState)),
|
Fun(emqttd_protocol:session(ProtoState)),
|
||||||
hibernate(State).
|
hibernate(State).
|
||||||
|
|
||||||
%% receive and parse tcp data
|
%% Receive and parse tcp data
|
||||||
received(<<>>, State) ->
|
received(<<>>, State) ->
|
||||||
hibernate(State);
|
hibernate(State);
|
||||||
|
|
||||||
|
|
|
@ -48,7 +48,7 @@ init([]) ->
|
||||||
|
|
||||||
%% CM Pool Sup
|
%% CM Pool Sup
|
||||||
MFA = {?CM, start_link, [emqttd_stats:statsfun('clients/count', 'clients/max')]},
|
MFA = {?CM, start_link, [emqttd_stats:statsfun('clients/count', 'clients/max')]},
|
||||||
PoolSup = emqttd_pool_sup:spec(pool_sup, [?CM, hash, erlang:system_info(schedulers), MFA]),
|
PoolSup = emqttd_pool_sup:spec([?CM, hash, erlang:system_info(schedulers), MFA]),
|
||||||
|
|
||||||
{ok, {{one_for_all, 10, 3600}, [PoolSup]}}.
|
{ok, {{one_for_all, 10, 3600}, [PoolSup]}}.
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,7 @@ handle_request('GET', "/status", Req) ->
|
||||||
AppStatus =
|
AppStatus =
|
||||||
case lists:keysearch(emqttd, 1, application:which_applications()) of
|
case lists:keysearch(emqttd, 1, application:which_applications()) of
|
||||||
false -> not_running;
|
false -> not_running;
|
||||||
{value, _Ver} -> running
|
{value, _Val} -> running
|
||||||
end,
|
end,
|
||||||
Status = io_lib:format("Node ~s is ~s~nemqttd is ~s",
|
Status = io_lib:format("Node ~s is ~s~nemqttd is ~s",
|
||||||
[node(), InternalStatus, AppStatus]),
|
[node(), InternalStatus, AppStatus]),
|
||||||
|
@ -78,7 +78,7 @@ handle_request('POST', "/mqtt/publish", Req) ->
|
||||||
%% MQTT Over WebSocket
|
%% MQTT Over WebSocket
|
||||||
%%------------------------------------------------------------------------------
|
%%------------------------------------------------------------------------------
|
||||||
handle_request('GET', "/mqtt", Req) ->
|
handle_request('GET', "/mqtt", Req) ->
|
||||||
lager:info("Websocket Connection from: ~s", [Req:get(peer)]),
|
lager:info("WebSocket Connection from: ~s", [Req:get(peer)]),
|
||||||
Upgrade = Req:get_header_value("Upgrade"),
|
Upgrade = Req:get_header_value("Upgrade"),
|
||||||
Proto = Req:get_header_value("Sec-WebSocket-Protocol"),
|
Proto = Req:get_header_value("Sec-WebSocket-Protocol"),
|
||||||
case {is_websocket(Upgrade), Proto} of
|
case {is_websocket(Upgrade), Proto} of
|
||||||
|
|
|
@ -35,10 +35,8 @@ merge(Defaults, Options) ->
|
||||||
lists:foldl(
|
lists:foldl(
|
||||||
fun({Opt, Val}, Acc) ->
|
fun({Opt, Val}, Acc) ->
|
||||||
case lists:keymember(Opt, 1, Acc) of
|
case lists:keymember(Opt, 1, Acc) of
|
||||||
true ->
|
true -> lists:keyreplace(Opt, 1, Acc, {Opt, Val});
|
||||||
lists:keyreplace(Opt, 1, Acc, {Opt, Val});
|
false -> [{Opt, Val}|Acc]
|
||||||
false ->
|
|
||||||
[{Opt, Val}|Acc]
|
|
||||||
end;
|
end;
|
||||||
(Opt, Acc) ->
|
(Opt, Acc) ->
|
||||||
case lists:member(Opt, Acc) of
|
case lists:member(Opt, Acc) of
|
||||||
|
|
|
@ -28,14 +28,18 @@
|
||||||
-behaviour(supervisor).
|
-behaviour(supervisor).
|
||||||
|
|
||||||
%% API
|
%% API
|
||||||
-export([spec/2, start_link/3, start_link/4]).
|
-export([spec/1, spec/2, start_link/3, start_link/4]).
|
||||||
|
|
||||||
%% Supervisor callbacks
|
%% Supervisor callbacks
|
||||||
-export([init/1]).
|
-export([init/1]).
|
||||||
|
|
||||||
|
-spec spec(list()) -> supervisor:child_spec().
|
||||||
|
spec(Args) ->
|
||||||
|
spec(pool_sup, Args).
|
||||||
|
|
||||||
-spec spec(any(), list()) -> supervisor:child_spec().
|
-spec spec(any(), list()) -> supervisor:child_spec().
|
||||||
spec(Id, Args) ->
|
spec(ChildId, Args) ->
|
||||||
{Id, {?MODULE, start_link, Args},
|
{ChildId, {?MODULE, start_link, Args},
|
||||||
transient, infinity, supervisor, [?MODULE]}.
|
transient, infinity, supervisor, [?MODULE]}.
|
||||||
|
|
||||||
-spec start_link(atom(), atom(), mfa()) -> {ok, pid()} | {error, any()}.
|
-spec start_link(atom(), atom(), mfa()) -> {ok, pid()} | {error, any()}.
|
||||||
|
@ -47,7 +51,7 @@ start_link(Pool, Type, MFA) ->
|
||||||
start_link(Pool, Type, Size, MFA) ->
|
start_link(Pool, Type, Size, MFA) ->
|
||||||
supervisor:start_link({local, sup_name(Pool)}, ?MODULE, [Pool, Type, Size, MFA]).
|
supervisor:start_link({local, sup_name(Pool)}, ?MODULE, [Pool, Type, Size, MFA]).
|
||||||
|
|
||||||
sup_name(Pool) ->
|
sup_name(Pool) when is_atom(Pool) ->
|
||||||
list_to_atom(atom_to_list(Pool) ++ "_pool_sup").
|
list_to_atom(atom_to_list(Pool) ++ "_pool_sup").
|
||||||
|
|
||||||
init([Pool, Type, Size, {M, F, Args}]) ->
|
init([Pool, Type, Size, {M, F, Args}]) ->
|
||||||
|
|
|
@ -63,16 +63,17 @@ name(Id) ->
|
||||||
%% @end
|
%% @end
|
||||||
%%------------------------------------------------------------------------------
|
%%------------------------------------------------------------------------------
|
||||||
submit(Fun) ->
|
submit(Fun) ->
|
||||||
Worker = gproc_pool:pick_worker(pooler),
|
gen_server:call(worker(), {submit, Fun}, infinity).
|
||||||
gen_server:call(Worker, {submit, Fun}, infinity).
|
|
||||||
|
|
||||||
%%------------------------------------------------------------------------------
|
%%------------------------------------------------------------------------------
|
||||||
%% @doc Submit work to pooler asynchronously
|
%% @doc Submit work to pooler asynchronously
|
||||||
%% @end
|
%% @end
|
||||||
%%------------------------------------------------------------------------------
|
%%------------------------------------------------------------------------------
|
||||||
async_submit(Fun) ->
|
async_submit(Fun) ->
|
||||||
Worker = gproc_pool:pick_worker(pooler),
|
gen_server:cast(worker(), {async_submit, Fun}).
|
||||||
gen_server:cast(Worker, {async_submit, Fun}).
|
|
||||||
|
worker() ->
|
||||||
|
gproc_pool:pick_worker(pooler).
|
||||||
|
|
||||||
%%%=============================================================================
|
%%%=============================================================================
|
||||||
%%% gen_server callbacks
|
%%% gen_server callbacks
|
||||||
|
|
|
@ -40,9 +40,9 @@
|
||||||
-copy_mnesia({mnesia, [copy]}).
|
-copy_mnesia({mnesia, [copy]}).
|
||||||
|
|
||||||
%% API Exports
|
%% API Exports
|
||||||
-export([start_link/3]).
|
-export([start_link/4]).
|
||||||
|
|
||||||
-export([create/1, subscribe/1, subscribe/2,
|
-export([create/2, subscribe/1, subscribe/2,
|
||||||
unsubscribe/1, unsubscribe/2, publish/1]).
|
unsubscribe/1, unsubscribe/2, publish/1]).
|
||||||
|
|
||||||
%% Local node
|
%% Local node
|
||||||
|
@ -56,7 +56,7 @@
|
||||||
-compile(export_all).
|
-compile(export_all).
|
||||||
-endif.
|
-endif.
|
||||||
|
|
||||||
-record(state, {pool, id}).
|
-record(state, {pool, id, statsfun}).
|
||||||
|
|
||||||
-define(ROUTER, emqttd_router).
|
-define(ROUTER, emqttd_router).
|
||||||
|
|
||||||
|
@ -123,26 +123,33 @@ cache_env(Key) ->
|
||||||
%% @doc Start one pubsub server
|
%% @doc Start one pubsub server
|
||||||
%% @end
|
%% @end
|
||||||
%%------------------------------------------------------------------------------
|
%%------------------------------------------------------------------------------
|
||||||
-spec start_link(Pool, Id, Opts) -> {ok, pid()} | ignore | {error, any()} when
|
-spec start_link(Pool, Id, StatsFun, Opts) -> {ok, pid()} | ignore | {error, any()} when
|
||||||
Pool :: atom(),
|
Pool :: atom(),
|
||||||
Id :: pos_integer(),
|
Id :: pos_integer(),
|
||||||
|
StatsFun :: fun(),
|
||||||
Opts :: list(tuple()).
|
Opts :: list(tuple()).
|
||||||
start_link(Pool, Id, Opts) ->
|
start_link(Pool, Id, StatsFun, Opts) ->
|
||||||
gen_server2:start_link({local, name(Id)}, ?MODULE, [Pool, Id, Opts], []).
|
gen_server2:start_link({local, name(Id)}, ?MODULE, [Pool, Id, StatsFun, Opts], []).
|
||||||
|
|
||||||
name(Id) ->
|
name(Id) ->
|
||||||
list_to_atom("emqttd_pubsub_" ++ integer_to_list(Id)).
|
list_to_atom("emqttd_pubsub_" ++ integer_to_list(Id)).
|
||||||
|
|
||||||
%%------------------------------------------------------------------------------
|
%%------------------------------------------------------------------------------
|
||||||
%% @doc Create Topic.
|
%% @doc Create Topic or Subscription.
|
||||||
%% @end
|
%% @end
|
||||||
%%------------------------------------------------------------------------------
|
%%------------------------------------------------------------------------------
|
||||||
-spec create(Topic :: binary()) -> ok | {error, Error :: any()}.
|
-spec create(topic | subscription, binary()) -> ok | {error, any()}.
|
||||||
create(Topic) when is_binary(Topic) ->
|
create(topic, Topic) when is_binary(Topic) ->
|
||||||
Record = #mqtt_topic{topic = Topic, node = node()},
|
Record = #mqtt_topic{topic = Topic, node = node()},
|
||||||
case mnesia:transaction(fun add_topic/1, [Record]) of
|
case mnesia:transaction(fun add_topic/1, [Record]) of
|
||||||
{atomic, ok} -> ok;
|
{atomic, ok} -> ok;
|
||||||
{aborted, Error} -> {error, Error}
|
{aborted, Error} -> {error, Error}
|
||||||
|
end;
|
||||||
|
|
||||||
|
create(subscription, {SubId, Topic, Qos}) ->
|
||||||
|
case mnesia:transaction(fun add_subscription/2, [SubId, {Topic, Qos}]) of
|
||||||
|
{atomic, ok} -> ok;
|
||||||
|
{aborted, Error} -> {error, Error}
|
||||||
end.
|
end.
|
||||||
|
|
||||||
%%------------------------------------------------------------------------------
|
%%------------------------------------------------------------------------------
|
||||||
|
@ -233,12 +240,13 @@ match(Topic) when is_binary(Topic) ->
|
||||||
%%% gen_server callbacks
|
%%% gen_server callbacks
|
||||||
%%%=============================================================================
|
%%%=============================================================================
|
||||||
|
|
||||||
init([Pool, Id, Opts]) ->
|
init([Pool, Id, StatsFun, Opts]) ->
|
||||||
?ROUTER:init(Opts),
|
?ROUTER:init(Opts),
|
||||||
?GPROC_POOL(join, Pool, Id),
|
?GPROC_POOL(join, Pool, Id),
|
||||||
{ok, #state{pool = Pool, id = Id}}.
|
{ok, #state{pool = Pool, id = Id, statsfun = StatsFun}}.
|
||||||
|
|
||||||
handle_call({subscribe, {SubId, SubPid}, TopicTable}, _From, State) ->
|
handle_call({subscribe, {SubId, SubPid}, TopicTable}, _From,
|
||||||
|
State = #state{statsfun = StatsFun}) ->
|
||||||
%% Add routes first
|
%% Add routes first
|
||||||
?ROUTER:add_routes(TopicTable, SubPid),
|
?ROUTER:add_routes(TopicTable, SubPid),
|
||||||
|
|
||||||
|
@ -247,11 +255,13 @@ handle_call({subscribe, {SubId, SubPid}, TopicTable}, _From, State) ->
|
||||||
|
|
||||||
case mnesia:transaction(fun add_topics/1, [Topics]) of
|
case mnesia:transaction(fun add_topics/1, [Topics]) of
|
||||||
{atomic, _} ->
|
{atomic, _} ->
|
||||||
|
StatsFun(topic),
|
||||||
if_subscription(
|
if_subscription(
|
||||||
fun(_) ->
|
fun(_) ->
|
||||||
%% Add subscriptions
|
%% Add subscriptions
|
||||||
Args = [fun add_subscriptions/2, [SubId, TopicTable]],
|
Args = [fun add_subscriptions/2, [SubId, TopicTable]],
|
||||||
emqttd_pooler:async_submit({mnesia, async_dirty, Args})
|
emqttd_pooler:async_submit({mnesia, async_dirty, Args}),
|
||||||
|
StatsFun(subscription)
|
||||||
end),
|
end),
|
||||||
{reply, {ok, [Qos || {_Topic, Qos} <- TopicTable]}, State};
|
{reply, {ok, [Qos || {_Topic, Qos} <- TopicTable]}, State};
|
||||||
{aborted, Error} ->
|
{aborted, Error} ->
|
||||||
|
@ -262,14 +272,16 @@ handle_call(Req, _From, State) ->
|
||||||
lager:error("Bad Request: ~p", [Req]),
|
lager:error("Bad Request: ~p", [Req]),
|
||||||
{reply, {error, badreq}, State}.
|
{reply, {error, badreq}, State}.
|
||||||
|
|
||||||
handle_cast({unsubscribe, {SubId, SubPid}, Topics}, State) ->
|
handle_cast({unsubscribe, {SubId, SubPid}, Topics}, State = #state{statsfun = StatsFun}) ->
|
||||||
%% Delete routes first
|
%% Delete routes first
|
||||||
?ROUTER:delete_routes(Topics, SubPid),
|
?ROUTER:delete_routes(Topics, SubPid),
|
||||||
|
|
||||||
%% Remove subscriptions
|
%% Remove subscriptions
|
||||||
if_subscription(
|
if_subscription(
|
||||||
fun(_) ->
|
fun(_) ->
|
||||||
Args = [fun remove_subscriptions/2, [SubId, Topics]],
|
Args = [fun remove_subscriptions/2, [SubId, Topics]],
|
||||||
emqttd_pooler:async_submit({mnesia, async_dirty, Args})
|
emqttd_pooler:async_submit({mnesia, async_dirty, Args}),
|
||||||
|
StatsFun(subscription)
|
||||||
end),
|
end),
|
||||||
{noreply, State};
|
{noreply, State};
|
||||||
|
|
||||||
|
@ -320,20 +332,36 @@ add_subscriptions(undefined, _TopicTable) ->
|
||||||
ok;
|
ok;
|
||||||
add_subscriptions(SubId, TopicTable) ->
|
add_subscriptions(SubId, TopicTable) ->
|
||||||
lists:foreach(fun({Topic, Qos}) ->
|
lists:foreach(fun({Topic, Qos}) ->
|
||||||
%%TODO: this is not right...
|
add_subscription(SubId, {Topic, Qos})
|
||||||
Subscription = #mqtt_subscription{subid = SubId, topic = Topic, qos = Qos},
|
|
||||||
mnesia:write(subscription, Subscription, write)
|
|
||||||
end,TopicTable).
|
end,TopicTable).
|
||||||
|
|
||||||
|
add_subscription(SubId, {Topic, Qos}) ->
|
||||||
|
Subscription = #mqtt_subscription{subid = SubId, topic = Topic, qos = Qos},
|
||||||
|
Pattern = #mqtt_subscription{subid = SubId, topic = Topic, qos = '_'},
|
||||||
|
Records = mnesia:match_object(subscription, Pattern, write),
|
||||||
|
case lists:member(Subscription, Records) of
|
||||||
|
true ->
|
||||||
|
ok;
|
||||||
|
false ->
|
||||||
|
[delete_subscription(Record) || Record <- Records],
|
||||||
|
insert_subscription(Subscription)
|
||||||
|
end.
|
||||||
|
|
||||||
|
insert_subscription(Record) ->
|
||||||
|
mnesia:write(subscription, Record, write).
|
||||||
|
|
||||||
remove_subscriptions(undefined, _Topics) ->
|
remove_subscriptions(undefined, _Topics) ->
|
||||||
ok;
|
ok;
|
||||||
remove_subscriptions(SubId, Topics) ->
|
remove_subscriptions(SubId, Topics) ->
|
||||||
lists:foreach(fun(Topic) ->
|
lists:foreach(fun(Topic) ->
|
||||||
Pattern = #mqtt_subscription{subid = SubId, topic = Topic, qos = '_'},
|
Pattern = #mqtt_subscription{subid = SubId, topic = Topic, qos = '_'},
|
||||||
[mnesia:delete_object(subscription, Subscription, write)
|
Records = mnesia:match_object(subscription, Pattern, write),
|
||||||
|| Subscription <- mnesia:match_object(subscription, Pattern, write)]
|
[delete_subscription(Record) || Record <- Records]
|
||||||
end, Topics).
|
end, Topics).
|
||||||
|
|
||||||
|
delete_subscription(Record) ->
|
||||||
|
mnesia:delete_object(subscription, Record, write).
|
||||||
|
|
||||||
%%%=============================================================================
|
%%%=============================================================================
|
||||||
%%% Trace Functions
|
%%% Trace Functions
|
||||||
%%%=============================================================================
|
%%%=============================================================================
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
-include("emqttd.hrl").
|
-include("emqttd.hrl").
|
||||||
|
|
||||||
%% API Function Exports
|
%% API Function Exports
|
||||||
-export([start_link/1, aging/1, setstats/1]).
|
-export([start_link/2, aging/1]).
|
||||||
|
|
||||||
%% gen_server Function Exports
|
%% gen_server Function Exports
|
||||||
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
|
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
|
||||||
|
@ -42,7 +42,7 @@
|
||||||
|
|
||||||
-record(aging, {topics, time, tref}).
|
-record(aging, {topics, time, tref}).
|
||||||
|
|
||||||
-record(state, {aging :: #aging{}}).
|
-record(state, {aging :: #aging{}, statsfun}).
|
||||||
|
|
||||||
-define(SERVER, ?MODULE).
|
-define(SERVER, ?MODULE).
|
||||||
|
|
||||||
|
@ -56,9 +56,9 @@
|
||||||
%% @doc Start pubsub helper.
|
%% @doc Start pubsub helper.
|
||||||
%% @end
|
%% @end
|
||||||
%%------------------------------------------------------------------------------
|
%%------------------------------------------------------------------------------
|
||||||
-spec start_link(list(tuple())) -> {ok, pid()} | ignore | {error, any()}.
|
-spec start_link(fun(), list(tuple())) -> {ok, pid()} | ignore | {error, any()}.
|
||||||
start_link(Opts) ->
|
start_link(StatsFun, Opts) ->
|
||||||
gen_server2:start_link({local, ?SERVER}, ?MODULE, [Opts], []).
|
gen_server2:start_link({local, ?SERVER}, ?MODULE, [StatsFun, Opts], []).
|
||||||
|
|
||||||
%%------------------------------------------------------------------------------
|
%%------------------------------------------------------------------------------
|
||||||
%% @doc Aging topics
|
%% @doc Aging topics
|
||||||
|
@ -68,19 +68,11 @@ start_link(Opts) ->
|
||||||
aging(Topics) ->
|
aging(Topics) ->
|
||||||
gen_server2:cast(?SERVER, {aging, Topics}).
|
gen_server2:cast(?SERVER, {aging, Topics}).
|
||||||
|
|
||||||
setstats(topic) ->
|
|
||||||
emqttd_stats:setstats('topics/count', 'topics/max',
|
|
||||||
mnesia:table_info(topic, size));
|
|
||||||
setstats(subscription) ->
|
|
||||||
emqttd_stats:setstats('subscriptions/count', 'subscriptions/max',
|
|
||||||
mnesia:table_info(subscription, size)).
|
|
||||||
|
|
||||||
%%%=============================================================================
|
%%%=============================================================================
|
||||||
%%% gen_server callbacks
|
%%% gen_server callbacks
|
||||||
%%%=============================================================================
|
%%%=============================================================================
|
||||||
|
|
||||||
init([Opts]) ->
|
init([StatsFun, Opts]) ->
|
||||||
|
|
||||||
mnesia:subscribe(system),
|
mnesia:subscribe(system),
|
||||||
|
|
||||||
AgingSecs = proplists:get_value(route_aging, Opts, 5),
|
AgingSecs = proplists:get_value(route_aging, Opts, 5),
|
||||||
|
@ -90,13 +82,15 @@ init([Opts]) ->
|
||||||
|
|
||||||
{ok, #state{aging = #aging{topics = dict:new(),
|
{ok, #state{aging = #aging{topics = dict:new(),
|
||||||
time = AgingSecs,
|
time = AgingSecs,
|
||||||
tref = AgingTref}}}.
|
tref = AgingTref},
|
||||||
|
statsfun = StatsFun}}.
|
||||||
|
|
||||||
start_tick(Secs) ->
|
start_tick(Secs) ->
|
||||||
timer:send_interval(timer:seconds(Secs), {clean, aged}).
|
timer:send_interval(timer:seconds(Secs), {clean, aged}).
|
||||||
|
|
||||||
handle_call(_Request, _From, State) ->
|
handle_call(Req, _From, State) ->
|
||||||
{reply, ok, State}.
|
lager:error("Unexpected Request: ~p", [Req]),
|
||||||
|
{reply, {error, unsupported_request}, State}.
|
||||||
|
|
||||||
handle_cast({aging, Topics}, State = #state{aging = Aging}) ->
|
handle_cast({aging, Topics}, State = #state{aging = Aging}) ->
|
||||||
#aging{topics = Dict} = Aging,
|
#aging{topics = Dict} = Aging,
|
||||||
|
@ -123,7 +117,7 @@ handle_info({clean, aged}, State = #state{aging = Aging}) ->
|
||||||
|
|
||||||
NewAging = Aging#aging{topics = dict:from_list(Dict1)},
|
NewAging = Aging#aging{topics = dict:from_list(Dict1)},
|
||||||
|
|
||||||
{noreply, State#state{aging = NewAging}, hibernate};
|
noreply(State#state{aging = NewAging});
|
||||||
|
|
||||||
handle_info({mnesia_system_event, {mnesia_down, Node}}, State) ->
|
handle_info({mnesia_system_event, {mnesia_down, Node}}, State) ->
|
||||||
Pattern = #mqtt_topic{_ = '_', node = Node},
|
Pattern = #mqtt_topic{_ = '_', node = Node},
|
||||||
|
@ -132,7 +126,7 @@ handle_info({mnesia_system_event, {mnesia_down, Node}}, State) ->
|
||||||
R <- mnesia:match_object(topic, Pattern, write)]
|
R <- mnesia:match_object(topic, Pattern, write)]
|
||||||
end,
|
end,
|
||||||
mnesia:async_dirty(F),
|
mnesia:async_dirty(F),
|
||||||
{noreply, State};
|
noreply(State);
|
||||||
|
|
||||||
handle_info(_Info, State) ->
|
handle_info(_Info, State) ->
|
||||||
{noreply, State}.
|
{noreply, State}.
|
||||||
|
@ -147,6 +141,9 @@ code_change(_OldVsn, State, _Extra) ->
|
||||||
%%% Internal Functions
|
%%% Internal Functions
|
||||||
%%%=============================================================================
|
%%%=============================================================================
|
||||||
|
|
||||||
|
noreply(State = #state{statsfun = StatsFun}) ->
|
||||||
|
StatsFun(topic), {noreply, State, hibernate}.
|
||||||
|
|
||||||
try_clean(ByTime, List) ->
|
try_clean(ByTime, List) ->
|
||||||
try_clean(ByTime, List, []).
|
try_clean(ByTime, List, []).
|
||||||
|
|
||||||
|
|
|
@ -42,16 +42,22 @@ start_link() ->
|
||||||
|
|
||||||
init([Opts]) ->
|
init([Opts]) ->
|
||||||
%% PubSub Helper
|
%% PubSub Helper
|
||||||
Helper = {helper, {?HELPER, start_link, [Opts]},
|
Helper = {helper, {?HELPER, start_link, [fun stats/1, Opts]},
|
||||||
permanent, infinity, worker, [?HELPER]},
|
permanent, infinity, worker, [?HELPER]},
|
||||||
|
|
||||||
%% PubSub Pool Sup
|
%% PubSub Pool Sup
|
||||||
MFA = {emqttd_pubsub, start_link, [Opts]},
|
MFA = {emqttd_pubsub, start_link, [fun stats/1, Opts]},
|
||||||
PoolSup = emqttd_pool_sup:spec(pool_sup, [
|
PoolSup = emqttd_pool_sup:spec([pubsub, hash, pool_size(Opts), MFA]),
|
||||||
pubsub, hash, pool_size(Opts), MFA]),
|
|
||||||
{ok, {{one_for_all, 10, 60}, [Helper, PoolSup]}}.
|
{ok, {{one_for_all, 10, 60}, [Helper, PoolSup]}}.
|
||||||
|
|
||||||
pool_size(Opts) ->
|
pool_size(Opts) ->
|
||||||
Schedulers = erlang:system_info(schedulers),
|
Schedulers = erlang:system_info(schedulers),
|
||||||
proplists:get_value(pool_size, Opts, Schedulers).
|
proplists:get_value(pool_size, Opts, Schedulers).
|
||||||
|
|
||||||
|
stats(topic) ->
|
||||||
|
emqttd_stats:setstats('topics/count', 'topics/max',
|
||||||
|
mnesia:table_info(topic, size));
|
||||||
|
stats(subscription) ->
|
||||||
|
emqttd_stats:setstats('subscriptions/count', 'subscriptions/max',
|
||||||
|
mnesia:table_info(subscription, size)).
|
||||||
|
|
||||||
|
|
|
@ -56,8 +56,7 @@ init([]) ->
|
||||||
|
|
||||||
%% SM Pool Sup
|
%% SM Pool Sup
|
||||||
MFA = {?SM, start_link, []},
|
MFA = {?SM, start_link, []},
|
||||||
PoolSup = emqttd_pool_sup:spec(pool_sup, [
|
PoolSup = emqttd_pool_sup:spec([?SM, hash, erlang:system_info(schedulers), MFA]),
|
||||||
?SM, hash, erlang:system_info(schedulers), MFA]),
|
|
||||||
|
|
||||||
{ok, {{one_for_all, 10, 3600}, [Helper, PoolSup]}}.
|
{ok, {{one_for_all, 10, 3600}, [Helper, PoolSup]}}.
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue