fix(gateway): keep the replay buffer across a session transfer (#2276)

This commit is contained in:
Hampus
2026-08-31 22:10:44 +02:00
committed by GitHub
parent 0f6b118921
commit 04e150e4bf
2 changed files with 33 additions and 1 deletions
@@ -552,6 +552,10 @@ serialize_transfer_identity(State) ->
debounce_reactions => maps:get(debounce_reactions, State, false)
}.
-spec transfer_buffer(eqwalizer:dynamic(limited_deque:deque() | [map()])) -> [term()].
transfer_buffer(Buffer) when is_list(Buffer) -> Buffer;
transfer_buffer(Buffer) -> limited_deque:to_list(Buffer).
-spec serialize_transfer_runtime(session_state()) -> map().
serialize_transfer_runtime(State) ->
#{
@@ -559,7 +563,7 @@ serialize_transfer_runtime(State) ->
relationships => maps:get(relationships, State, #{}),
seq => maps:get(seq, State, 0),
ack_seq => maps:get(ack_seq, State, 0),
buffer => maps:get(buffer, State, []),
buffer => transfer_buffer(maps:get(buffer, State, [])),
collected_guild_states => maps:get(collected_guild_states, State, []),
collected_sessions => maps:get(collected_sessions, State, []),
collected_presences => maps:get(collected_presences, State, []),
@@ -108,6 +108,34 @@ serialize_transfer_state_strips_socket_pid_test() ->
TransferState = session_lifecycle:serialize_transfer_state(State),
?assertEqual(undefined, maps:get(socket_pid, TransferState)).
serialize_transfer_state_preserves_deque_replay_buffer_test() ->
Deque = lists:foldl(
fun(Seq, Acc) ->
limited_deque:push(#{event => message_create, data => #{}, seq => Seq}, Acc)
end,
limited_deque:new(4096, 16777216),
[1000, 1001]
),
State = #{
id => <<"session-deque-transfer">>,
user_id => 42,
user_data => #{},
version => 9,
token_hash => <<"token_hash">>,
auth_session_id_hash => <<"auth_hash">>,
properties => #{},
status => online,
afk => false,
mobile => false,
ready => undefined,
seq => 1001,
ack_seq => 999,
buffer => Deque
},
TransferState = session_lifecycle:serialize_transfer_state(State),
Restored = session_init:normalize_buffer(maps:get(buffer, TransferState)),
?assertEqual([1000, 1001], [maps:get(seq, Event) || Event <- Restored]).
heartbeat_ack_recalculates_buffer_bytes_test() ->
Event1 = #{seq => 1, event => message_create, data => #{<<"content">> => <<"one">>}},
Event2 = #{seq => 2, event => message_create, data => #{<<"content">> => <<"two">>}},