Skip to content

Commit

Permalink
Merge pull request #4089 from esl/no-extra-get-session-call-for-prese…
Browse files Browse the repository at this point in the history
…nces

Avoid calling ejabberd_sm_backend:get_sessions/3 second time when routing presences

Old code calls get_session_pid for each presence. Again.
We could avoid it.

Proposed changes include:
    Introduce get_user_present_resources_and_pids, call it in do_route_no_resource function

Why:
    Slightly faster, because CETS does not need lookup and call tuple_to_session function again
    We do a lot of presences (could be 80% of traffic), so an optimisation matters
  • Loading branch information
NelsonVides authored Aug 9, 2023
2 parents 45e214f + 594eb9b commit 04f9591
Showing 1 changed file with 14 additions and 6 deletions.
20 changes: 14 additions & 6 deletions src/ejabberd_sm.erl
Original file line number Diff line number Diff line change
Expand Up @@ -642,13 +642,14 @@ do_route_no_resource(<<"presence">>, From, To, Acc, El) ->
Type = mongoose_acc:stanza_type(Acc),
case do_route_no_resource_presence(Type, From, To, Acc, El) of
true ->
PResources = get_user_present_resources(To),
lists:foldl(fun({_, R}, A) ->
NewTo = jid:replace_resource(To, R),
ResourcesPids = get_user_present_resources_and_pids(To),
lists:foldl(fun({Resource, Pid}, Acc1) ->
NewTo = jid:replace_resource(To, Resource),
NewAccParams = #{element => El, from_jid => From, to_jid => NewTo},
A0 = mongoose_acc:update_stanza(NewAccParams, A),
do_route(A0, From, NewTo, El)
end, Acc, PResources);
Acc2 = mongoose_acc:update_stanza(NewAccParams, Acc1),
mongoose_c2s:route(Pid, Acc2),
Acc2
end, Acc, ResourcesPids);
false ->
Acc
end;
Expand Down Expand Up @@ -801,6 +802,13 @@ get_user_present_pids(LUser, LServer) ->
[{S#session.priority, element(2, S#session.sid)} ||
S <- clean_session_list(Ss), is_integer(S#session.priority)].

-spec get_user_present_resources_and_pids(jid:jid()) -> [{Resource :: binary(), pid()}].
get_user_present_resources_and_pids(#jid{luser = LUser, lserver = LServer}) ->
Ss = ejabberd_sm_backend:get_sessions(LUser, LServer),
[{Resource, Pid} ||
#session{usr = {_, _, Resource}, sid = {_, Pid}, priority = Prio}
<- clean_session_list(Ss), is_integer(Prio)].

-spec get_user_present_resources(jid:jid()) -> [{priority(), binary()}].
get_user_present_resources(#jid{luser = LUser, lserver = LServer}) ->
Ss = ejabberd_sm_backend:get_sessions(LUser, LServer),
Expand Down

0 comments on commit 04f9591

Please sign in to comment.