aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRapptz <[email protected]>2021-07-29 01:43:23 -0400
committerRapptz <[email protected]>2021-07-29 01:43:23 -0400
commitecf239d2a2e6ee8e027ca5fef9acf4564a9f3a09 (patch)
tree5a1b817691786602e4b0348b8a25b9d20277df13
parentAdd Guild.get_channel_or_thread helper method (diff)
downloaddiscord.py-ecf239d2a2e6ee8e027ca5fef9acf4564a9f3a09.tar.xz
discord.py-ecf239d2a2e6ee8e027ca5fef9acf4564a9f3a09.zip
Fix user cache acting incorrectly with evictions
The first issue involved copied users which would lead to user updates causing faster evictions of the cache than was expected. The second issue involved users that weren't bound to an internal lifetime eviction policy. These users would not get evicted. For example, a user without mutual guilds or being part of the internal cache in general (messages, DMs) would never end up being evicted for some strange reason. To handle this case, store_user would get a counterpart named create_user which would create a user without potentially storing them in the cache. That way only users with a bound lifetime within the library would be stored.
-rw-r--r--discord/appinfo.py2
-rw-r--r--discord/interactions.py3
-rw-r--r--discord/invite.py4
-rw-r--r--discord/member.py2
-rw-r--r--discord/state.py4
-rw-r--r--discord/template.py2
-rw-r--r--discord/user.py2
-rw-r--r--discord/webhook/async_.py3
8 files changed, 14 insertions, 8 deletions
diff --git a/discord/appinfo.py b/discord/appinfo.py
index 67082abd..de1f7a73 100644
--- a/discord/appinfo.py
+++ b/discord/appinfo.py
@@ -146,7 +146,7 @@ class AppInfo:
self.rpc_origins: List[str] = data['rpc_origins']
self.bot_public: bool = data['bot_public']
self.bot_require_code_grant: bool = data['bot_require_code_grant']
- self.owner: User = state.store_user(data['owner'])
+ self.owner: User = state.create_user(data['owner'])
team: Optional[TeamPayload] = data.get('team')
self.team: Optional[Team] = Team(state, team) if team else None
diff --git a/discord/interactions.py b/discord/interactions.py
index 217e107f..667c6773 100644
--- a/discord/interactions.py
+++ b/discord/interactions.py
@@ -626,6 +626,9 @@ class _InteractionMessageState:
def store_user(self, data):
return self._parent.store_user(data)
+ def create_user(self, data):
+ return self._parent.create_user(data)
+
@property
def http(self):
return self._parent.http
diff --git a/discord/invite.py b/discord/invite.py
index 288438c9..d02fa680 100644
--- a/discord/invite.py
+++ b/discord/invite.py
@@ -352,12 +352,12 @@ class Invite(Hashable):
self.expires_at: Optional[datetime.datetime] = parse_time(expires_at) if expires_at else None
inviter_data = data.get('inviter')
- self.inviter: Optional[User] = None if inviter_data is None else self._state.store_user(inviter_data)
+ self.inviter: Optional[User] = None if inviter_data is None else self._state.create_user(inviter_data)
self.channel: Optional[InviteChannelType] = self._resolve_channel(data.get('channel'), channel)
target_user_data = data.get('target_user')
- self.target_user: Optional[User] = None if target_user_data is None else self._state.store_user(target_user_data)
+ self.target_user: Optional[User] = None if target_user_data is None else self._state.create_user(target_user_data)
self.target_type: InviteTarget = try_enum(InviteTarget, data.get("target_type", 0))
diff --git a/discord/member.py b/discord/member.py
index 2cc8cc92..84d6adfb 100644
--- a/discord/member.py
+++ b/discord/member.py
@@ -326,7 +326,7 @@ class Member(discord.abc.Messageable, _UserTag):
try:
member_data = data.pop('member')
except KeyError:
- return state.store_user(data)
+ return state.create_user(data)
else:
member_data['user'] = data # type: ignore
return cls(data=member_data, guild=guild, state=state) # type: ignore
diff --git a/discord/state.py b/discord/state.py
index b98a0a8e..fd0587bf 100644
--- a/discord/state.py
+++ b/discord/state.py
@@ -178,7 +178,7 @@ class ConnectionState:
self._intents = intents
if not intents.members or cache_flags._empty:
- self.store_user = self.store_user_no_intents
+ self.store_user = self.create_user
self.deref_user = self.deref_user_no_intents
self.parsers = parsers = {}
@@ -284,7 +284,7 @@ class ConnectionState:
def deref_user(self, user_id):
self._users.pop(user_id, None)
- def store_user_no_intents(self, data):
+ def create_user(self, data):
return User(state=self, data=data)
def deref_user_no_intents(self, user_id):
diff --git a/discord/template.py b/discord/template.py
index 045e1878..12429c71 100644
--- a/discord/template.py
+++ b/discord/template.py
@@ -137,7 +137,7 @@ class Template:
self.name = data['name']
self.description = data['description']
creator_data = data.get('creator')
- self.creator = None if creator_data is None else self._state.store_user(creator_data)
+ self.creator = None if creator_data is None else self._state.create_user(creator_data)
self.created_at = parse_time(data.get('created_at'))
self.updated_at = parse_time(data.get('updated_at'))
diff --git a/discord/user.py b/discord/user.py
index cad78e0c..e45426ac 100644
--- a/discord/user.py
+++ b/discord/user.py
@@ -393,7 +393,7 @@ class User(BaseUser, discord.abc.Messageable):
@classmethod
def _copy(cls, user):
self = super()._copy(user)
- self._stored = getattr(user, '_stored', False)
+ self._stored = False
return self
async def _get_channel(self):
diff --git a/discord/webhook/async_.py b/discord/webhook/async_.py
index c5e93408..58bbbd21 100644
--- a/discord/webhook/async_.py
+++ b/discord/webhook/async_.py
@@ -597,6 +597,9 @@ class _WebhookState:
return self._parent.store_user(data)
return BaseUser(state=self, data=data)
+ def create_user(self, data):
+ return BaseUser(state=self, data=data)
+
@property
def http(self):
if self._parent is not None: