remove mnesia index
This commit is contained in:
parent
c29fd68dd5
commit
f4d09c973d
|
@ -51,11 +51,11 @@
|
||||||
%% gen_server2 priorities
|
%% gen_server2 priorities
|
||||||
-export([prioritise_call/4, prioritise_cast/3, prioritise_info/3]).
|
-export([prioritise_call/4, prioritise_cast/3, prioritise_info/3]).
|
||||||
|
|
||||||
-record(state, {pool, id}).
|
-record(state, {pool, id, monitors}).
|
||||||
|
|
||||||
-define(POOL, ?MODULE).
|
-define(POOL, ?MODULE).
|
||||||
|
|
||||||
-define(TIMEOUT, 60000).
|
-define(TIMEOUT, 120000).
|
||||||
|
|
||||||
-define(LOG(Level, Format, Args, Session),
|
-define(LOG(Level, Format, Args, Session),
|
||||||
lager:Level("SM(~s): " ++ Format, [Session#mqtt_session.client_id | Args])).
|
lager:Level("SM(~s): " ++ Format, [Session#mqtt_session.client_id | Args])).
|
||||||
|
@ -67,12 +67,11 @@
|
||||||
mnesia(boot) ->
|
mnesia(boot) ->
|
||||||
%% Global Session Table
|
%% Global Session Table
|
||||||
ok = emqttd_mnesia:create_table(session, [
|
ok = emqttd_mnesia:create_table(session, [
|
||||||
{type, ordered_set},
|
{type, set},
|
||||||
{ram_copies, [node()]},
|
{ram_copies, [node()]},
|
||||||
{record_name, mqtt_session},
|
{record_name, mqtt_session},
|
||||||
{attributes, record_info(fields, mqtt_session)},
|
{attributes, record_info(fields, mqtt_session)}]);
|
||||||
%% TODO: index_read is slow...
|
|
||||||
{index, [sess_pid]}]);
|
|
||||||
mnesia(copy) ->
|
mnesia(copy) ->
|
||||||
ok = emqttd_mnesia:copy_table(session).
|
ok = emqttd_mnesia:copy_table(session).
|
||||||
|
|
||||||
|
@ -144,7 +143,8 @@ call(SM, Req) ->
|
||||||
|
|
||||||
init([Pool, Id]) ->
|
init([Pool, Id]) ->
|
||||||
?GPROC_POOL(join, Pool, Id),
|
?GPROC_POOL(join, Pool, Id),
|
||||||
{ok, #state{pool = Pool, id = Id}}.
|
{ok, #state{pool = Pool, id = Id,
|
||||||
|
monitors = dict:new()}}.
|
||||||
|
|
||||||
prioritise_call(_Msg, _From, _Len, _State) ->
|
prioritise_call(_Msg, _From, _Len, _State) ->
|
||||||
1.
|
1.
|
||||||
|
@ -155,43 +155,57 @@ prioritise_cast(_Msg, _Len, _State) ->
|
||||||
prioritise_info(_Msg, _Len, _State) ->
|
prioritise_info(_Msg, _Len, _State) ->
|
||||||
2.
|
2.
|
||||||
|
|
||||||
%% persistent session
|
%% Persistent Session
|
||||||
handle_call({start_session, {false, ClientId, ClientPid}}, _From, State) ->
|
handle_call({start_session, Client = {false, ClientId, ClientPid}}, _From, State) ->
|
||||||
case lookup_session(ClientId) of
|
case lookup_session(ClientId) of
|
||||||
undefined ->
|
undefined ->
|
||||||
%% create session locally
|
%% Create session locally
|
||||||
reply(create_session(false, ClientId, ClientPid), false, State);
|
create_session(Client, State);
|
||||||
Session ->
|
Session ->
|
||||||
reply(resume_session(Session, ClientPid), true, State)
|
case resume_session(Session, ClientPid) of
|
||||||
|
{ok, SessPid} ->
|
||||||
|
{reply, {ok, SessPid, true}, State};
|
||||||
|
{error, Erorr} ->
|
||||||
|
{reply, {error, Erorr}, State}
|
||||||
|
end
|
||||||
end;
|
end;
|
||||||
|
|
||||||
%% transient session
|
%% Transient Session
|
||||||
handle_call({start_session, {true, ClientId, ClientPid}}, _From, State) ->
|
handle_call({start_session, Client = {true, ClientId, _ClientPid}}, _From, State) ->
|
||||||
case lookup_session(ClientId) of
|
case lookup_session(ClientId) of
|
||||||
undefined ->
|
undefined ->
|
||||||
reply(create_session(true, ClientId, ClientPid), false, State);
|
create_session(Client, State);
|
||||||
Session ->
|
Session ->
|
||||||
case destroy_session(Session) of
|
case destroy_session(Session) of
|
||||||
ok ->
|
ok ->
|
||||||
reply(create_session(true, ClientId, ClientPid), false, State);
|
create_session(Client, State);
|
||||||
{error, Error} ->
|
{error, Error} ->
|
||||||
{reply, {error, Error}, State}
|
{reply, {error, Error}, State}
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
|
|
||||||
handle_call(_Request, _From, State) ->
|
handle_call(Req, _From, State) ->
|
||||||
{reply, ok, State}.
|
?UNEXPECTED_REQ(Req, State).
|
||||||
|
|
||||||
handle_cast(Msg, State) ->
|
handle_cast(Msg, State) ->
|
||||||
?UNEXPECTED_MSG(Msg, State).
|
?UNEXPECTED_MSG(Msg, State).
|
||||||
|
|
||||||
%%TODO: fix this issue that index_read is really slow...
|
handle_info({'DOWN', MRef, process, DownPid, _Reason}, State) ->
|
||||||
handle_info({'DOWN', _MRef, process, DownPid, _Reason}, State) ->
|
case dict:find(MRef, State#state.monitors) of
|
||||||
|
{ok, ClientId} ->
|
||||||
mnesia:transaction(fun() ->
|
mnesia:transaction(fun() ->
|
||||||
[mnesia:delete_object(session, Sess, write) || Sess
|
case mnesia:wread({session, ClientId}) of
|
||||||
<- mnesia:index_read(session, DownPid, #mqtt_session.sess_pid)]
|
[] -> ok;
|
||||||
|
[Sess = #mqtt_session{sess_pid = DownPid}] ->
|
||||||
|
mnesia:delete_object(session, Sess, write);
|
||||||
|
[_Sess] -> ok
|
||||||
|
end
|
||||||
end),
|
end),
|
||||||
{noreply, State};
|
{noreply, erase_monitor(MRef, State)};
|
||||||
|
error ->
|
||||||
|
lager:error("MRef of session ~p not found", [DownPid]),
|
||||||
|
{noreply, State}
|
||||||
|
end;
|
||||||
|
|
||||||
handle_info(Info, State) ->
|
handle_info(Info, State) ->
|
||||||
?UNEXPECTED_INFO(Info, State).
|
?UNEXPECTED_INFO(Info, State).
|
||||||
|
@ -206,6 +220,16 @@ code_change(_OldVsn, State, _Extra) ->
|
||||||
%%% Internal functions
|
%%% Internal functions
|
||||||
%%%=============================================================================
|
%%%=============================================================================
|
||||||
|
|
||||||
|
%% Create Session Locally
|
||||||
|
create_session({CleanSess, ClientId, ClientPid}, State) ->
|
||||||
|
case create_session(CleanSess, ClientId, ClientPid) of
|
||||||
|
{ok, SessPid} ->
|
||||||
|
{reply, {ok, SessPid, false},
|
||||||
|
monitor_session(ClientId, SessPid, State)};
|
||||||
|
{error, Error} ->
|
||||||
|
{reply, {error, Error}, State}
|
||||||
|
end.
|
||||||
|
|
||||||
create_session(CleanSess, ClientId, ClientPid) ->
|
create_session(CleanSess, ClientId, ClientPid) ->
|
||||||
case emqttd_session_sup:start_session(CleanSess, ClientId, ClientPid) of
|
case emqttd_session_sup:start_session(CleanSess, ClientId, ClientPid) of
|
||||||
{ok, SessPid} ->
|
{ok, SessPid} ->
|
||||||
|
@ -218,7 +242,6 @@ create_session(CleanSess, ClientId, ClientPid) ->
|
||||||
lager:error("SM(~s): Conflict with ~p", [ClientId, ConflictPid]),
|
lager:error("SM(~s): Conflict with ~p", [ClientId, ConflictPid]),
|
||||||
{error, mnesia_conflict};
|
{error, mnesia_conflict};
|
||||||
{atomic, ok} ->
|
{atomic, ok} ->
|
||||||
erlang:monitor(process, SessPid),
|
|
||||||
{ok, SessPid}
|
{ok, SessPid}
|
||||||
end;
|
end;
|
||||||
{error, Error} ->
|
{error, Error} ->
|
||||||
|
@ -293,8 +316,10 @@ remove_session(Session) ->
|
||||||
{aborted, Error} -> {error, Error}
|
{aborted, Error} -> {error, Error}
|
||||||
end.
|
end.
|
||||||
|
|
||||||
reply({ok, SessPid}, SP, State) ->
|
monitor_session(ClientId, SessPid, State = #state{monitors = Monitors}) ->
|
||||||
{reply, {ok, SessPid, SP}, State};
|
MRef = erlang:monitor(process, SessPid),
|
||||||
reply({error, Error}, _SP, State) ->
|
State#state{monitors = dict:store(MRef, ClientId, Monitors)}.
|
||||||
{reply, {error, Error}, State}.
|
|
||||||
|
erase_monitor(MRef, State = #state{monitors = Monitors}) ->
|
||||||
|
State#state{monitors = dict:erase(MRef, Monitors)}.
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue