mirror of
https://github.com/fluxerapp/fluxer.git
synced 2026-09-03 05:10:25 +03:00
fix(gateway): register the session process with presence on resume (#1715)
This commit is contained in:
@@ -84,11 +84,14 @@ code_change(_OldVsn, State, _Extra) ->
|
||||
-spec handle_call(term(), gen_server:from(), state()) ->
|
||||
{reply, term(), state()} | {stop, normal, ok, state()}.
|
||||
handle_call({session_connect, Request}, {Pid, _}, State) when is_map(Request), is_pid(Pid) ->
|
||||
{reply, Reply, NewState} = presence_session:handle_session_connect(Request, Pid, State),
|
||||
SessionPid = session_connect_pid(Request, Pid),
|
||||
{reply, Reply, NewState} = presence_session:handle_session_connect(
|
||||
Request, SessionPid, State
|
||||
),
|
||||
FinalState = presence_broadcast:publish_global_presence(
|
||||
maps:get(sessions, NewState), NewState
|
||||
),
|
||||
presence_broadcast:send_cached_presences_to_session(Pid, FinalState),
|
||||
presence_broadcast:send_cached_presences_to_session(SessionPid, FinalState),
|
||||
{reply, Reply, FinalState};
|
||||
handle_call(get_current_visible_presence, _From, State) ->
|
||||
{reply, presence_broadcast:current_visible_presence(State), State};
|
||||
@@ -141,6 +144,12 @@ handle_cast({sync_group_dm_recipients, RecipientsByChannel}, State) when
|
||||
handle_cast(Msg, State) ->
|
||||
handle_cast_guild(Msg, State).
|
||||
|
||||
-spec session_connect_pid(map(), pid()) -> pid().
|
||||
session_connect_pid(#{session_pid := Pid}, _CallerPid) when is_pid(Pid) ->
|
||||
Pid;
|
||||
session_connect_pid(_Request, CallerPid) ->
|
||||
CallerPid.
|
||||
|
||||
-spec handle_sync_friends_cast([term()], [term()], state()) -> {noreply, state()}.
|
||||
handle_sync_friends_cast(FriendIds, FlushedIds, State) ->
|
||||
{noreply,
|
||||
@@ -280,6 +289,14 @@ normalize_start_link(ignore) ->
|
||||
-ifdef(TEST).
|
||||
-include_lib("eunit/include/eunit.hrl").
|
||||
|
||||
session_connect_pid_prefers_request_session_pid_test() ->
|
||||
Caller = self(),
|
||||
Other = spawn(fun idle_session_proc/0),
|
||||
?assertEqual(Other, session_connect_pid(#{session_pid => Other}, Caller)),
|
||||
?assertEqual(Caller, session_connect_pid(#{}, Caller)),
|
||||
?assertEqual(Caller, session_connect_pid(#{session_pid => undefined}, Caller)),
|
||||
Other ! stop.
|
||||
|
||||
presence_rejoin_notifies_all_sessions_test() ->
|
||||
Parent = self(),
|
||||
Session1 = spawn(fun() -> rejoin_check_receiver(Parent, one) end),
|
||||
@@ -349,6 +366,13 @@ test_session_entry(Pid) ->
|
||||
socket_pid => undefined
|
||||
}.
|
||||
|
||||
-spec idle_session_proc() -> ok.
|
||||
idle_session_proc() ->
|
||||
receive
|
||||
stop -> ok
|
||||
after 1000 -> ok
|
||||
end.
|
||||
|
||||
-spec rejoin_check_receiver(pid(), atom()) -> term().
|
||||
rejoin_check_receiver(Parent, Tag) ->
|
||||
receive
|
||||
|
||||
@@ -414,21 +414,22 @@ handle_resume_offline_timeout(_Msg, State) ->
|
||||
ok.
|
||||
notify_presence_on_resume(#{presence_pid := undefined}, _Sid, _St, _Afk, _Mob) ->
|
||||
ok;
|
||||
notify_presence_on_resume(#{presence_pid := Pid}, SessionId, Status, Afk, Mobile) ->
|
||||
spawn(fun() -> notify_presence_on_resume_worker(Pid, SessionId, Status, Afk, Mobile) end),
|
||||
notify_presence_on_resume(#{presence_pid := Pid} = State, SessionId, Status, Afk, Mobile) ->
|
||||
Request = #{
|
||||
session_id => SessionId,
|
||||
session_pid => self(),
|
||||
socket_pid => maps:get(socket_pid, State, undefined),
|
||||
status => Status,
|
||||
afk => Afk,
|
||||
mobile => Mobile
|
||||
},
|
||||
spawn(fun() -> notify_presence_on_resume_worker(Pid, Request) end),
|
||||
ok.
|
||||
|
||||
-spec notify_presence_on_resume_worker(pid(), session_id(), status(), boolean(), boolean()) ->
|
||||
ok.
|
||||
notify_presence_on_resume_worker(Pid, SessionId, Status, Afk, Mobile) ->
|
||||
-spec notify_presence_on_resume_worker(pid(), map()) -> ok.
|
||||
notify_presence_on_resume_worker(Pid, Request) ->
|
||||
try
|
||||
gen_server:call(
|
||||
Pid,
|
||||
{session_connect, #{
|
||||
session_id => SessionId, status => Status, afk => Afk, mobile => Mobile
|
||||
}},
|
||||
10000
|
||||
),
|
||||
gen_server:call(Pid, {session_connect, Request}, 10000),
|
||||
ok
|
||||
catch
|
||||
error:_Reason -> ok;
|
||||
|
||||
@@ -363,6 +363,31 @@ resume_success_state(State0) ->
|
||||
{reply, {ok, _Missed, 1}, State1} = session_lifecycle:handle_resume(0, self(), State0),
|
||||
State1.
|
||||
|
||||
handle_resume_registers_the_session_process_with_presence_test() ->
|
||||
SessionPid = self(),
|
||||
Presence = spawn(fun() -> fake_presence_loop(SessionPid) end),
|
||||
State0 = resume_test_state(#{presence_pid => Presence, seq => 1}),
|
||||
{reply, {ok, [], 1}, _State1} = session_lifecycle:handle_resume(1, self(), State0),
|
||||
receive
|
||||
{presence_session_connect, Request} ->
|
||||
?assertEqual(SessionPid, maps:get(session_pid, Request)),
|
||||
?assertEqual(<<"session-resume-test">>, maps:get(session_id, Request))
|
||||
after 2000 ->
|
||||
?assert(false, presence_session_connect_not_received)
|
||||
end.
|
||||
|
||||
fake_presence_loop(Parent) ->
|
||||
receive
|
||||
{'$gen_call', From, {session_connect, Request}} ->
|
||||
Parent ! {presence_session_connect, Request},
|
||||
gen_server:reply(From, {ok, []}),
|
||||
fake_presence_loop(Parent);
|
||||
_Other ->
|
||||
fake_presence_loop(Parent)
|
||||
after 5000 ->
|
||||
ok
|
||||
end.
|
||||
|
||||
resume_test_state(Overrides) ->
|
||||
maps:merge(
|
||||
#{
|
||||
|
||||
Reference in New Issue
Block a user