diff options
| author | Rapptz <[email protected]> | 2017-07-04 20:01:27 -0400 |
|---|---|---|
| committer | Rapptz <[email protected]> | 2017-07-04 20:02:17 -0400 |
| commit | 3bd0c2120c1d05fe49fd9a873b0b0e4aedd43066 (patch) | |
| tree | d9a10cf0de5c8d15b0104f00706f002a7e831d0c | |
| parent | Don't unnecessarily re-create private channels. (diff) | |
| download | discord.py-3bd0c2120c1d05fe49fd9a873b0b0e4aedd43066.tar.xz discord.py-3bd0c2120c1d05fe49fd9a873b0b0e4aedd43066.zip | |
Implement a LRU cache for private channels.
Another fix related to the discord issue[1].
[1]: https://github.com/hammerandchisel/discord-api-docs/issues/184
| -rw-r--r-- | discord/client.py | 8 | ||||
| -rw-r--r-- | discord/state.py | 24 |
2 files changed, 27 insertions, 5 deletions
diff --git a/discord/client.py b/discord/client.py index 6304fb4e..2c5ed69c 100644 --- a/discord/client.py +++ b/discord/client.py @@ -179,7 +179,13 @@ class Client: @property def private_channels(self): - """List[:class:`abc.PrivateChannel`]: The private channels that the connected client is participating on.""" + """List[:class:`abc.PrivateChannel`]: The private channels that the connected client is participating on. + + .. note:: + + This returns only up to 128 most recent private channels due to an internal working + on how Discord deals with private channels. + """ return self._connection.private_channels @property diff --git a/discord/state.py b/discord/state.py index fa74a384..f2ed8244 100644 --- a/discord/state.py +++ b/discord/state.py @@ -37,7 +37,7 @@ from .calls import GroupCall from . import utils, compat from .embeds import Embed -from collections import deque, namedtuple +from collections import deque, namedtuple, OrderedDict import copy, enum, math import datetime import asyncio @@ -89,7 +89,9 @@ class ConnectionState: self._calls = {} self._guilds = {} self._voice_clients = {} - self._private_channels = {} + + # LRU of max size 128 + self._private_channels = OrderedDict() # extra dict to look up private channels by user id self._private_channels_by_user = {} self._messages = deque(maxlen=self.max_messages) @@ -189,13 +191,27 @@ class ConnectionState: return list(self._private_channels.values()) def _get_private_channel(self, channel_id): - return self._private_channels.get(channel_id) + try: + value = self._private_channels[channel_id] + except KeyError: + return None + else: + self._private_channels.move_to_end(channel_id) + return value def _get_private_channel_by_user(self, user_id): return self._private_channels_by_user.get(user_id) def _add_private_channel(self, channel): - self._private_channels[channel.id] = channel + channel_id = channel.id + self._private_channels[channel_id] = channel + + if len(self._private_channels) > 128: + _, to_remove = self._private_channels.popitem(last=False) + print(to_remove) + if isinstance(to_remove, DMChannel): + self._private_channels_by_user.pop(to_remove.recipient.id, None) + if isinstance(channel, DMChannel): self._private_channels_by_user[channel.recipient.id] = channel |