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 @property
def private_channels(self): 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 return self._connection.private_channels
@property @property

24
discord/state.py

@ -37,7 +37,7 @@ from .calls import GroupCall
from . import utils, compat from . import utils, compat
from .embeds import Embed from .embeds import Embed
from collections import deque, namedtuple from collections import deque, namedtuple, OrderedDict
import copy, enum, math import copy, enum, math
import datetime import datetime
import asyncio import asyncio
@ -89,7 +89,9 @@ class ConnectionState:
self._calls = {} self._calls = {}
self._guilds = {} self._guilds = {}
self._voice_clients = {} 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 # extra dict to look up private channels by user id
self._private_channels_by_user = {} self._private_channels_by_user = {}
self._messages = deque(maxlen=self.max_messages) self._messages = deque(maxlen=self.max_messages)
@ -189,13 +191,27 @@ class ConnectionState:
return list(self._private_channels.values()) return list(self._private_channels.values())
def _get_private_channel(self, channel_id): 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): def _get_private_channel_by_user(self, user_id):
return self._private_channels_by_user.get(user_id) return self._private_channels_by_user.get(user_id)
def _add_private_channel(self, channel): 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): if isinstance(channel, DMChannel):
self._private_channels_by_user[channel.recipient.id] = channel self._private_channels_by_user[channel.recipient.id] = channel

Loading…
Cancel
Save