refactor(session): update eviction channel session logic
The changes partially reflect `emqx_channel` changes with respect to in-memory session specific logic. The difference is that eviction channel does not replay post-takeover, instead enqueues messages.
This commit is contained in:
parent
ab1c4c4222
commit
45d44df11d
|
|
@ -1177,7 +1177,7 @@ handle_call(
|
||||||
ok = emqx_session_mem:takeover(Session),
|
ok = emqx_session_mem:takeover(Session),
|
||||||
%% TODO: Should not drain deliver here (side effect)
|
%% TODO: Should not drain deliver here (side effect)
|
||||||
Delivers = emqx_utils:drain_deliver(),
|
Delivers = emqx_utils:drain_deliver(),
|
||||||
AllPendings = lists:append(Delivers, Pendings),
|
AllPendings = lists:append(Pendings, maybe_nack(Delivers)),
|
||||||
?tp(
|
?tp(
|
||||||
debug,
|
debug,
|
||||||
emqx_channel_takeover_end,
|
emqx_channel_takeover_end,
|
||||||
|
|
|
||||||
|
|
@ -100,7 +100,8 @@
|
||||||
resume/2,
|
resume/2,
|
||||||
enqueue/3,
|
enqueue/3,
|
||||||
dequeue/2,
|
dequeue/2,
|
||||||
replay/2
|
replay/2,
|
||||||
|
dedup/4
|
||||||
]).
|
]).
|
||||||
|
|
||||||
%% Export for CT
|
%% Export for CT
|
||||||
|
|
@ -669,19 +670,10 @@ resume(ClientInfo = #{clientid := ClientId}, Session = #session{subscriptions =
|
||||||
-spec replay(emqx_types:clientinfo(), [emqx_types:message()], session()) ->
|
-spec replay(emqx_types:clientinfo(), [emqx_types:message()], session()) ->
|
||||||
{ok, replies(), session()}.
|
{ok, replies(), session()}.
|
||||||
replay(ClientInfo, Pendings, Session) ->
|
replay(ClientInfo, Pendings, Session) ->
|
||||||
PendingsLocal = emqx_session:enrich_delivers(
|
PendingsAll = dedup(ClientInfo, Pendings, emqx_utils:drain_deliver(), Session),
|
||||||
ClientInfo,
|
|
||||||
emqx_utils:drain_deliver(),
|
|
||||||
Session
|
|
||||||
),
|
|
||||||
PendingsLocal1 = lists:filter(
|
|
||||||
fun(Msg) -> not lists:keymember(Msg#message.id, #message.id, Pendings) end,
|
|
||||||
PendingsLocal
|
|
||||||
),
|
|
||||||
{ok, PubsResendQueued, Session1} = replay(ClientInfo, Session),
|
{ok, PubsResendQueued, Session1} = replay(ClientInfo, Session),
|
||||||
{ok, Pubs1, Session2} = deliver(ClientInfo, Pendings, Session1),
|
{ok, PubsPending, Session2} = deliver(ClientInfo, PendingsAll, Session1),
|
||||||
{ok, Pubs2, Session3} = deliver(ClientInfo, PendingsLocal1, Session2),
|
{ok, append(PubsResendQueued, PubsPending), Session2}.
|
||||||
{ok, append(append(PubsResendQueued, Pubs1), Pubs2), Session3}.
|
|
||||||
|
|
||||||
-spec replay(emqx_types:clientinfo(), session()) ->
|
-spec replay(emqx_types:clientinfo(), session()) ->
|
||||||
{ok, replies(), session()}.
|
{ok, replies(), session()}.
|
||||||
|
|
@ -698,6 +690,16 @@ replay(ClientInfo, Session) ->
|
||||||
{ok, More, Session1} = dequeue(ClientInfo, Session),
|
{ok, More, Session1} = dequeue(ClientInfo, Session),
|
||||||
{ok, append(PubsResend, More), Session1}.
|
{ok, append(PubsResend, More), Session1}.
|
||||||
|
|
||||||
|
-spec dedup(clientinfo(), [emqx_types:message()], [emqx_types:deliver()], session()) ->
|
||||||
|
[emqx_types:message()].
|
||||||
|
dedup(ClientInfo, Pendings, DeliversLocal, Session) ->
|
||||||
|
PendingsLocal1 = emqx_session:enrich_delivers(ClientInfo, DeliversLocal, Session),
|
||||||
|
PendingsLocal2 = lists:filter(
|
||||||
|
fun(Msg) -> not lists:keymember(Msg#message.id, #message.id, Pendings) end,
|
||||||
|
PendingsLocal1
|
||||||
|
),
|
||||||
|
append(Pendings, PendingsLocal2).
|
||||||
|
|
||||||
append(L1, []) -> L1;
|
append(L1, []) -> L1;
|
||||||
append(L1, L2) -> L1 ++ L2.
|
append(L1, L2) -> L1 ++ L2.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,6 @@
|
||||||
|
|
||||||
-include_lib("emqx/include/emqx.hrl").
|
-include_lib("emqx/include/emqx.hrl").
|
||||||
-include_lib("emqx/include/emqx_channel.hrl").
|
-include_lib("emqx/include/emqx_channel.hrl").
|
||||||
-include_lib("emqx/include/emqx_mqtt.hrl").
|
|
||||||
-include_lib("emqx/include/logger.hrl").
|
-include_lib("emqx/include/logger.hrl").
|
||||||
-include_lib("emqx/include/types.hrl").
|
-include_lib("emqx/include/types.hrl").
|
||||||
|
|
||||||
|
|
@ -122,7 +121,9 @@ handle_call(
|
||||||
pendings := Pendings
|
pendings := Pendings
|
||||||
} = Channel
|
} = Channel
|
||||||
) ->
|
) ->
|
||||||
ok = emqx_session:takeover(Session),
|
% NOTE
|
||||||
|
% This is essentially part of `emqx_session_mem` logic, thus call it directly.
|
||||||
|
ok = emqx_session_mem:takeover(Session),
|
||||||
%% TODO: Should not drain deliver here (side effect)
|
%% TODO: Should not drain deliver here (side effect)
|
||||||
Delivers = emqx_utils:drain_deliver(),
|
Delivers = emqx_utils:drain_deliver(),
|
||||||
AllPendings = lists:append(Delivers, Pendings),
|
AllPendings = lists:append(Delivers, Pendings),
|
||||||
|
|
@ -196,8 +197,11 @@ handle_deliver(
|
||||||
clientinfo := ClientInfo
|
clientinfo := ClientInfo
|
||||||
} = Channel
|
} = Channel
|
||||||
) ->
|
) ->
|
||||||
|
% NOTE
|
||||||
|
% This is essentially part of `emqx_session_mem` logic, thus call it directly.
|
||||||
Delivers1 = emqx_channel:maybe_nack(Delivers),
|
Delivers1 = emqx_channel:maybe_nack(Delivers),
|
||||||
NSession = emqx_session:enqueue(ClientInfo, Delivers1, Session),
|
Messages = emqx_session:enrich_delivers(ClientInfo, Delivers1, Session),
|
||||||
|
NSession = emqx_session_mem:enqueue(ClientInfo, Messages, Session),
|
||||||
Channel#{session := NSession}.
|
Channel#{session := NSession}.
|
||||||
|
|
||||||
cancel_expiry_timer(#{expiry_timer := TRef}) when is_reference(TRef) ->
|
cancel_expiry_timer(#{expiry_timer := TRef}) when is_reference(TRef) ->
|
||||||
|
|
@ -230,7 +234,7 @@ open_session(ConnInfo, #{clientid := ClientId} = ClientInfo) ->
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
{error, no_session};
|
{error, no_session};
|
||||||
{ok, #{session := Session, present := true, pendings := Pendings0}} ->
|
{ok, #{session := Session, present := true, replay := Pendings}} ->
|
||||||
?SLOG(
|
?SLOG(
|
||||||
info,
|
info,
|
||||||
#{
|
#{
|
||||||
|
|
@ -239,12 +243,9 @@ open_session(ConnInfo, #{clientid := ClientId} = ClientInfo) ->
|
||||||
node => node()
|
node => node()
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
Pendings1 = lists:usort(lists:append(Pendings0, emqx_utils:drain_deliver())),
|
DeliversLocal = emqx_channel:maybe_nack(emqx_utils:drain_deliver()),
|
||||||
NSession = emqx_session:enqueue(
|
PendingsAll = emqx_session_mem:dedup(ClientInfo, Pendings, DeliversLocal, Session),
|
||||||
ClientInfo,
|
NSession = emqx_session_mem:enqueue(ClientInfo, PendingsAll, Session),
|
||||||
emqx_channel:maybe_nack(Pendings1),
|
|
||||||
Session
|
|
||||||
),
|
|
||||||
NChannel = Channel#{session => NSession},
|
NChannel = Channel#{session => NSession},
|
||||||
ok = emqx_cm:insert_channel_info(ClientId, info(NChannel), stats(NChannel)),
|
ok = emqx_cm:insert_channel_info(ClientId, info(NChannel), stats(NChannel)),
|
||||||
?SLOG(
|
?SLOG(
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue