Browse Source

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
pull/631/head
Rapptz 8 years ago
parent
commit
3bd0c2120c
  1. 8
      discord/client.py
  2. 24
      discord/state.py

8
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

24
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

Loading…
Cancel
Save