mirror of
https://github.com/fluxerapp/fluxer
synced 2026-10-18 21:45:31 +09:00
fix(gateway): register the session process with presence on resume (#1715)
This commit is contained in:
1 parent
5ce5669f17
commit
7d82d188a0
3 files changed
+64
-14
No files matched your search
@@ -84,11 +84,14 @@ code_change(_OldVsn, State, _Extra) ->
|
|||||||
-spec handle_call(term(), gen_server:from(), state()) ->
|
-spec handle_call(term(), gen_server:from(), state()) ->
|
||||||
{reply, term(), state()} | {stop, normal, ok, state()}.
|
{reply, term(), state()} | {stop, normal, ok, state()}.
|
||||||
handle_call({session_connect, Request}, {Pid, _}, State) when is_map(Request), is_pid(Pid) ->
|
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(
|
FinalState = presence_broadcast:publish_global_presence(
|
||||||
maps:get(sessions, NewState), NewState
|
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};
|
{reply, Reply, FinalState};
|
||||||
handle_call(get_current_visible_presence, _From, State) ->
|
handle_call(get_current_visible_presence, _From, State) ->
|
||||||
{reply, presence_broadcast:current_visible_presence(State), 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(Msg, State) ->
|
||||||
handle_cast_guild(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()}.
|
-spec handle_sync_friends_cast([term()], [term()], state()) -> {noreply, state()}.
|
||||||
handle_sync_friends_cast(FriendIds, FlushedIds, State) ->
|
handle_sync_friends_cast(FriendIds, FlushedIds, State) ->
|
||||||
{noreply,
|
{noreply,
|
||||||
@@ -280,6 +289,14 @@ normalize_start_link(ignore) ->
|
|||||||
-ifdef(TEST).
|
-ifdef(TEST).
|
||||||
-include_lib("eunit/include/eunit.hrl").
|
-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() ->
|
presence_rejoin_notifies_all_sessions_test() ->
|
||||||
Parent = self(),
|
Parent = self(),
|
||||||
Session1 = spawn(fun() -> rejoin_check_receiver(Parent, one) end),
|
Session1 = spawn(fun() -> rejoin_check_receiver(Parent, one) end),
|
||||||
@@ -349,6 +366,13 @@ test_session_entry(Pid) ->
|
|||||||
socket_pid => undefined
|
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().
|
-spec rejoin_check_receiver(pid(), atom()) -> term().
|
||||||
rejoin_check_receiver(Parent, Tag) ->
|
rejoin_check_receiver(Parent, Tag) ->
|
||||||
receive
|
receive
|
||||||
|
|||||||
@@ -414,21 +414,22 @@ handle_resume_offline_timeout(_Msg, State) ->
|
|||||||
ok.
|
ok.
|
||||||
notify_presence_on_resume(#{presence_pid := undefined}, _Sid, _St, _Afk, _Mob) ->
|
notify_presence_on_resume(#{presence_pid := undefined}, _Sid, _St, _Afk, _Mob) ->
|
||||||
ok;
|
ok;
|
||||||
notify_presence_on_resume(#{presence_pid := Pid}, SessionId, Status, Afk, Mobile) ->
|
notify_presence_on_resume(#{presence_pid := Pid} = State, SessionId, Status, Afk, Mobile) ->
|
||||||
spawn(fun() -> notify_presence_on_resume_worker(Pid, SessionId, Status, Afk, Mobile) end),
|
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.
|
ok.
|
||||||
|
|
||||||
-spec notify_presence_on_resume_worker(pid(), session_id(), status(), boolean(), boolean()) ->
|
-spec notify_presence_on_resume_worker(pid(), map()) -> ok.
|
||||||
ok.
|
notify_presence_on_resume_worker(Pid, Request) ->
|
||||||
notify_presence_on_resume_worker(Pid, SessionId, Status, Afk, Mobile) ->
|
|
||||||
try
|
try
|
||||||
gen_server:call(
|
gen_server:call(Pid, {session_connect, Request}, 10000),
|
||||||
Pid,
|
|
||||||
{session_connect, #{
|
|
||||||
session_id => SessionId, status => Status, afk => Afk, mobile => Mobile
|
|
||||||
}},
|
|
||||||
10000
|
|
||||||
),
|
|
||||||
ok
|
ok
|
||||||
catch
|
catch
|
||||||
error:_Reason -> ok;
|
error:_Reason -> ok;
|
||||||
|
|||||||
@@ -363,6 +363,31 @@ resume_success_state(State0) ->
|
|||||||
{reply, {ok, _Missed, 1}, State1} = session_lifecycle:handle_resume(0, self(), State0),
|
{reply, {ok, _Missed, 1}, State1} = session_lifecycle:handle_resume(0, self(), State0),
|
||||||
State1.
|
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) ->
|
resume_test_state(Overrides) ->
|
||||||
maps:merge(
|
maps:merge(
|
||||||
#{
|
#{
|
||||||
|
|||||||
Reference in new issue
Block a user