refactor(cm): avoid deep indirection in `emqx_session_mem`
This commit is contained in:
parent
abeff0bc4f
commit
2dae8020ec
|
@ -52,7 +52,8 @@
|
||||||
open_session/3,
|
open_session/3,
|
||||||
discard_session/1,
|
discard_session/1,
|
||||||
discard_session/2,
|
discard_session/2,
|
||||||
takeover_channel_session/2,
|
takeover_session_begin/1,
|
||||||
|
takeover_session_end/1,
|
||||||
kick_session/1,
|
kick_session/1,
|
||||||
kick_session/2
|
kick_session/2
|
||||||
]).
|
]).
|
||||||
|
@ -118,6 +119,8 @@
|
||||||
_Stats :: emqx_types:stats()
|
_Stats :: emqx_types:stats()
|
||||||
}.
|
}.
|
||||||
|
|
||||||
|
-type takeover_state() :: {_ConnMod :: module(), _ChanPid :: pid()}.
|
||||||
|
|
||||||
-define(CHAN_STATS, [
|
-define(CHAN_STATS, [
|
||||||
{?CHAN_TAB, 'channels.count', 'channels.max'},
|
{?CHAN_TAB, 'channels.count', 'channels.max'},
|
||||||
{?CHAN_TAB, 'sessions.count', 'sessions.max'},
|
{?CHAN_TAB, 'sessions.count', 'sessions.max'},
|
||||||
|
@ -289,28 +292,32 @@ create_register_session(ClientInfo = #{clientid := ClientId}, ConnInfo, ChanPid)
|
||||||
{ok, #{session => Session, present => false}}.
|
{ok, #{session => Session, present => false}}.
|
||||||
|
|
||||||
%% @doc Try to takeover a session from existing channel.
|
%% @doc Try to takeover a session from existing channel.
|
||||||
%% Naming is wierd, because `takeover_session/2` is an RPC target and cannot be renamed.
|
-spec takeover_session_begin(emqx_types:clientid()) ->
|
||||||
-spec takeover_channel_session(emqx_types:clientid(), _TODO) ->
|
{ok, emqx_session_mem:session(), takeover_state()} | none.
|
||||||
{ok, emqx_session:session(), _ReplayContext} | none | {error, _Reason}.
|
takeover_session_begin(ClientId) ->
|
||||||
takeover_channel_session(ClientId, OnTakeover) ->
|
takeover_session_begin(ClientId, pick_channel(ClientId)).
|
||||||
takeover_channel_session(ClientId, pick_channel(ClientId), OnTakeover).
|
|
||||||
|
|
||||||
takeover_channel_session(ClientId, ChanPid, OnTakeover) when is_pid(ChanPid) ->
|
takeover_session_begin(ClientId, ChanPid) when is_pid(ChanPid) ->
|
||||||
case takeover_session(ClientId, ChanPid) of
|
case takeover_session(ClientId, ChanPid) of
|
||||||
{living, ConnMod, Session} ->
|
{living, ConnMod, Session} ->
|
||||||
Session1 = OnTakeover(Session),
|
{ok, Session, {ConnMod, ChanPid}};
|
||||||
case wrap_rpc(emqx_cm_proto_v2:takeover_finish(ConnMod, ChanPid)) of
|
|
||||||
{ok, Pendings} ->
|
|
||||||
{ok, Session1, Pendings};
|
|
||||||
{error, _} = Error ->
|
|
||||||
Error
|
|
||||||
end;
|
|
||||||
none ->
|
none ->
|
||||||
none
|
none
|
||||||
end;
|
end;
|
||||||
takeover_channel_session(_ClientId, undefined, _OnTakeover) ->
|
takeover_session_begin(_ClientId, undefined) ->
|
||||||
none.
|
none.
|
||||||
|
|
||||||
|
%% @doc Conclude the session takeover process.
|
||||||
|
-spec takeover_session_end(takeover_state()) ->
|
||||||
|
{ok, _ReplayContext} | {error, _Reason}.
|
||||||
|
takeover_session_end({ConnMod, ChanPid}) ->
|
||||||
|
case wrap_rpc(emqx_cm_proto_v2:takeover_finish(ConnMod, ChanPid)) of
|
||||||
|
{ok, Pendings} ->
|
||||||
|
{ok, Pendings};
|
||||||
|
{error, _} = Error ->
|
||||||
|
Error
|
||||||
|
end.
|
||||||
|
|
||||||
-spec pick_channel(emqx_types:clientid()) ->
|
-spec pick_channel(emqx_types:clientid()) ->
|
||||||
maybe(pid()).
|
maybe(pid()).
|
||||||
pick_channel(ClientId) ->
|
pick_channel(ClientId) ->
|
||||||
|
|
|
@ -196,17 +196,16 @@ destroy(_Session) ->
|
||||||
-spec open(clientinfo(), emqx_types:conninfo()) ->
|
-spec open(clientinfo(), emqx_types:conninfo()) ->
|
||||||
{true, session(), replayctx()} | false.
|
{true, session(), replayctx()} | false.
|
||||||
open(ClientInfo = #{clientid := ClientId}, _ConnInfo) ->
|
open(ClientInfo = #{clientid := ClientId}, _ConnInfo) ->
|
||||||
case
|
case emqx_cm:takeover_session_begin(ClientId) of
|
||||||
emqx_cm:takeover_channel_session(
|
{ok, SessionRemote, TakeoverState} ->
|
||||||
ClientId,
|
Session = resume(ClientInfo, SessionRemote),
|
||||||
fun(Session) -> resume(ClientInfo, Session) end
|
case emqx_cm:takeover_session_end(TakeoverState) of
|
||||||
)
|
{ok, Pendings} ->
|
||||||
of
|
|
||||||
{ok, Session, Pendings} ->
|
|
||||||
clean_session(ClientInfo, Session, Pendings);
|
clean_session(ClientInfo, Session, Pendings);
|
||||||
{error, _} ->
|
{error, _} ->
|
||||||
% TODO log error?
|
% TODO log error?
|
||||||
false;
|
false
|
||||||
|
end;
|
||||||
none ->
|
none ->
|
||||||
false
|
false
|
||||||
end.
|
end.
|
||||||
|
|
|
@ -321,7 +321,7 @@ test_stepdown_session(Action, Reason) ->
|
||||||
discard ->
|
discard ->
|
||||||
emqx_cm:discard_session(ClientId);
|
emqx_cm:discard_session(ClientId);
|
||||||
{takeover, _} ->
|
{takeover, _} ->
|
||||||
none = emqx_cm:takeover_channel_session(ClientId, fun ident/1),
|
none = emqx_cm:takeover_session_begin(ClientId),
|
||||||
ok
|
ok
|
||||||
end,
|
end,
|
||||||
case Reason =:= timeout orelse Reason =:= noproc of
|
case Reason =:= timeout orelse Reason =:= noproc of
|
||||||
|
@ -381,10 +381,11 @@ t_discard_session_race(_) ->
|
||||||
|
|
||||||
t_takeover_session(_) ->
|
t_takeover_session(_) ->
|
||||||
#{conninfo := ConnInfo} = ?ChanInfo,
|
#{conninfo := ConnInfo} = ?ChanInfo,
|
||||||
none = emqx_cm:takeover_channel_session(<<"clientid">>, fun ident/1),
|
ClientId = <<"clientid">>,
|
||||||
|
none = emqx_cm:takeover_session_begin(ClientId),
|
||||||
Parent = self(),
|
Parent = self(),
|
||||||
erlang:spawn_link(fun() ->
|
ChanPid = erlang:spawn_link(fun() ->
|
||||||
ok = emqx_cm:register_channel(<<"clientid">>, self(), ConnInfo),
|
ok = emqx_cm:register_channel(ClientId, self(), ConnInfo),
|
||||||
Parent ! registered,
|
Parent ! registered,
|
||||||
receive
|
receive
|
||||||
{'$gen_call', From1, {takeover, 'begin'}} ->
|
{'$gen_call', From1, {takeover, 'begin'}} ->
|
||||||
|
@ -398,16 +399,17 @@ t_takeover_session(_) ->
|
||||||
receive
|
receive
|
||||||
registered -> ok
|
registered -> ok
|
||||||
end,
|
end,
|
||||||
{ok, test, []} = emqx_cm:takeover_channel_session(<<"clientid">>, fun ident/1),
|
{ok, test, State = {emqx_connection, ChanPid}} = emqx_cm:takeover_session_begin(ClientId),
|
||||||
emqx_cm:unregister_channel(<<"clientid">>).
|
{ok, []} = emqx_cm:takeover_session_end(State),
|
||||||
|
emqx_cm:unregister_channel(ClientId).
|
||||||
|
|
||||||
t_takeover_session_process_gone(_) ->
|
t_takeover_session_process_gone(_) ->
|
||||||
#{conninfo := ConnInfo} = ?ChanInfo,
|
#{conninfo := ConnInfo} = ?ChanInfo,
|
||||||
ClientIDTcp = <<"clientidTCP">>,
|
ClientIDTcp = <<"clientidTCP">>,
|
||||||
ClientIDWs = <<"clientidWs">>,
|
ClientIDWs = <<"clientidWs">>,
|
||||||
ClientIDRpc = <<"clientidRPC">>,
|
ClientIDRpc = <<"clientidRPC">>,
|
||||||
none = emqx_cm:takeover_channel_session(ClientIDTcp, fun ident/1),
|
none = emqx_cm:takeover_session_begin(ClientIDTcp),
|
||||||
none = emqx_cm:takeover_channel_session(ClientIDWs, fun ident/1),
|
none = emqx_cm:takeover_session_begin(ClientIDWs),
|
||||||
meck:new(emqx_connection, [passthrough, no_history]),
|
meck:new(emqx_connection, [passthrough, no_history]),
|
||||||
meck:expect(
|
meck:expect(
|
||||||
emqx_connection,
|
emqx_connection,
|
||||||
|
@ -420,7 +422,7 @@ t_takeover_session_process_gone(_) ->
|
||||||
end
|
end
|
||||||
),
|
),
|
||||||
ok = emqx_cm:register_channel(ClientIDTcp, self(), ConnInfo),
|
ok = emqx_cm:register_channel(ClientIDTcp, self(), ConnInfo),
|
||||||
none = emqx_cm:takeover_channel_session(ClientIDTcp, fun ident/1),
|
none = emqx_cm:takeover_session_begin(ClientIDTcp),
|
||||||
meck:expect(
|
meck:expect(
|
||||||
emqx_connection,
|
emqx_connection,
|
||||||
call,
|
call,
|
||||||
|
@ -432,7 +434,7 @@ t_takeover_session_process_gone(_) ->
|
||||||
end
|
end
|
||||||
),
|
),
|
||||||
ok = emqx_cm:register_channel(ClientIDWs, self(), ConnInfo),
|
ok = emqx_cm:register_channel(ClientIDWs, self(), ConnInfo),
|
||||||
none = emqx_cm:takeover_channel_session(ClientIDWs, fun ident/1),
|
none = emqx_cm:takeover_session_begin(ClientIDWs),
|
||||||
meck:expect(
|
meck:expect(
|
||||||
emqx_connection,
|
emqx_connection,
|
||||||
call,
|
call,
|
||||||
|
@ -444,7 +446,7 @@ t_takeover_session_process_gone(_) ->
|
||||||
end
|
end
|
||||||
),
|
),
|
||||||
ok = emqx_cm:register_channel(ClientIDRpc, self(), ConnInfo),
|
ok = emqx_cm:register_channel(ClientIDRpc, self(), ConnInfo),
|
||||||
none = emqx_cm:takeover_channel_session(ClientIDRpc, fun ident/1),
|
none = emqx_cm:takeover_session_begin(ClientIDRpc),
|
||||||
emqx_cm:unregister_channel(ClientIDTcp),
|
emqx_cm:unregister_channel(ClientIDTcp),
|
||||||
emqx_cm:unregister_channel(ClientIDWs),
|
emqx_cm:unregister_channel(ClientIDWs),
|
||||||
emqx_cm:unregister_channel(ClientIDRpc),
|
emqx_cm:unregister_channel(ClientIDRpc),
|
||||||
|
@ -463,8 +465,3 @@ t_message(_) ->
|
||||||
?CM ! testing,
|
?CM ! testing,
|
||||||
gen_server:cast(?CM, testing),
|
gen_server:cast(?CM, testing),
|
||||||
gen_server:call(?CM, testing).
|
gen_server:call(?CM, testing).
|
||||||
|
|
||||||
%%
|
|
||||||
|
|
||||||
ident(V) ->
|
|
||||||
V.
|
|
||||||
|
|
Loading…
Reference in New Issue