fix(gateway): keep ets tids opaque in the permission cache (#2654)

This commit is contained in:
Hampus
2026-09-11 01:31:58 +02:00
committed by GitHub
parent b29da84282
commit 2e8f381efc
@@ -134,15 +134,25 @@ get_snapshot(_) ->
{error, not_found}. {error, not_found}.
-spec snapshot_with_live_members(guild_state()) -> {ok, guild_state()} | {error, not_found}. -spec snapshot_with_live_members(guild_state()) -> {ok, guild_state()} | {error, not_found}.
snapshot_with_live_members(#{data := #{members_ets := Tab}} = Snapshot) when snapshot_with_live_members(Snapshot) ->
is_reference(Tab) case snapshot_member_table(Snapshot) of
-> Tab when is_reference(Tab) -> live_member_table_snapshot(Tab, Snapshot);
undefined -> {ok, Snapshot}
end.
-spec live_member_table_snapshot(ets:tid(), guild_state()) ->
{ok, guild_state()} | {error, not_found}.
live_member_table_snapshot(Tab, Snapshot) ->
case ets:info(Tab, owner) of case ets:info(Tab, owner) of
undefined -> {error, not_found}; undefined -> {error, not_found};
_ -> {ok, Snapshot} _ -> {ok, Snapshot}
end; end.
snapshot_with_live_members(Snapshot) ->
{ok, Snapshot}. -spec snapshot_member_table(guild_state()) -> ets:tid() | undefined.
snapshot_member_table(#{data := Data}) when is_map(Data) ->
data_member_table(Data);
snapshot_member_table(_Snapshot) ->
undefined.
-spec safe_member_read(fun(() -> {ok, term()})) -> {ok, term()} | {error, not_found}. -spec safe_member_read(fun(() -> {ok, term()})) -> {ok, term()} | {error, not_found}.
safe_member_read(Read) -> safe_member_read(Read) ->
@@ -155,10 +165,11 @@ safe_member_read(Read) ->
-spec project_member(guild_state(), map() | undefined) -> map() | undefined. -spec project_member(guild_state(), map() | undefined) -> map() | undefined.
project_member(_Snapshot, undefined) -> project_member(_Snapshot, undefined) ->
undefined; undefined;
project_member(#{data := #{members_ets := Tab}}, Member) when is_reference(Tab) -> project_member(Snapshot, Member) ->
strip_member(Member); case snapshot_member_table(Snapshot) of
project_member(_Snapshot, Member) -> Tab when is_reference(Tab) -> strip_member(Member);
Member. undefined -> Member
end.
-spec ensure_table() -> ok. -spec ensure_table() -> ok.
ensure_table() -> ensure_table() ->
@@ -196,16 +207,25 @@ with_member_source(Data, Base) ->
end. end.
-spec shared_member_table(guild_data()) -> {ok, ets:tid()} | none. -spec shared_member_table(guild_data()) -> {ok, ets:tid()} | none.
shared_member_table(#{members_ets := Tab}) when is_reference(Tab) -> shared_member_table(Data) ->
Readable = case {members_ets_enabled(), data_member_table(Data)} of
members_ets_enabled() andalso ets:info(Tab, type) =:= set andalso {true, Tab} when is_reference(Tab) -> readable_member_table(Tab);
lists:member(ets:info(Tab, protection), [public, protected]), _ -> none
case Readable of end.
true -> {ok, Tab};
false -> none -spec readable_member_table(ets:tid()) -> {ok, ets:tid()} | none.
end; readable_member_table(Tab) ->
shared_member_table(_Data) -> case {ets:info(Tab, type), ets:info(Tab, protection)} of
none. {set, public} -> {ok, Tab};
{set, protected} -> {ok, Tab};
_ -> none
end.
-spec data_member_table(guild_data()) -> ets:tid() | undefined.
data_member_table(#{members_ets := Tab}) ->
Tab;
data_member_table(_Data) ->
undefined.
-spec members_ets_enabled() -> boolean(). -spec members_ets_enabled() -> boolean().
members_ets_enabled() -> members_ets_enabled() ->