Merge pull request #9119 from emqx/1009-fix-sticky-dispatch-should-check-subscription-table

fix(shared): check sticky if sticky pid is still a member
This commit is contained in:
Zaiming (Stone) Shi 2022-10-10 08:51:51 +02:00 committed by GitHub
commit 4989e57ebb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 12 additions and 3 deletions

View File

@ -58,6 +58,12 @@ File format:
- For wildcard deliveries, the re-dispatch used the wrong topic (the publishing topic, - For wildcard deliveries, the re-dispatch used the wrong topic (the publishing topic,
but not the subscribing topic), caused messages to be lost when dispatching. but not the subscribing topic), caused messages to be lost when dispatching.
- Fix shared subscription group member unsubscribe issue when 'sticky' strategy is used.
Prior to this fix, if a previously picked member unsubscribes from the group (without reconnect)
the message is still dispatched to it.
This issue only occurs when unsubscribe with the session kept.
Fixed in [#9119](https://github.com/emqx/emqx/pull/9119)
## v4.3.20 ## v4.3.20
### Bug fixes ### Bug fixes

View File

@ -337,7 +337,8 @@ fetch_sender_ref({Sender, Ref}) -> {Sender, Ref}.
pick(sticky, ClientId, SourceTopic, Group, Topic, FailedSubs) -> pick(sticky, ClientId, SourceTopic, Group, Topic, FailedSubs) ->
Sub0 = erlang:get({shared_sub_sticky, Group, Topic}), Sub0 = erlang:get({shared_sub_sticky, Group, Topic}),
case is_active_sub(Sub0, FailedSubs) of All = subscribers(Group, Topic),
case is_active_sub(Sub0, FailedSubs, All) of
true -> true ->
%% the old subscriber is still alive %% the old subscriber is still alive
%% keep using it for sticky strategy %% keep using it for sticky strategy
@ -507,8 +508,10 @@ update_stats(State) ->
State. State.
%% Return 'true' if the subscriber process is alive AND not in the failed list %% Return 'true' if the subscriber process is alive AND not in the failed list
is_active_sub(Pid, FailedSubs) -> is_active_sub(Pid, FailedSubs, All) ->
not maps:is_key(Pid, FailedSubs) andalso is_alive_sub(Pid). lists:member(Pid, All) andalso
(not maps:is_key(Pid, FailedSubs)) andalso
is_alive_sub(Pid).
%% erlang:is_process_alive/1 does not work with remote pid. %% erlang:is_process_alive/1 does not work with remote pid.
is_alive_sub(Pid) when ?IS_LOCAL_PID(Pid) -> is_alive_sub(Pid) when ?IS_LOCAL_PID(Pid) ->