Browse Source

Fix the way cached presences work

There where various oddities and bugs here, namely:

- Guild kept its initial `presences` list even though this is basically
useless, and was never kept up-to-date
- State did not properly use all the fields of presence_update, and was
creating some annoying recursive oddities w/ user and presence binding
feature/storage
Andrei 8 years ago
parent
commit
b340440ec1
  1. 1
      disco/gateway/events.py
  2. 31
      disco/state.py
  3. 3
      disco/types/guild.py

1
disco/gateway/events.py

@ -153,6 +153,7 @@ class GuildCreate(GatewayEvent):
and if None, this is a normal guild join event.
"""
unavailable = Field(bool)
presences = ListField(Presence)
@property
def created(self):

31
disco/state.py

@ -315,15 +315,30 @@ class State(object):
self.guilds[event.guild_id].emojis = HashMap({i.id: i for i in event.emojis})
def on_presence_update(self, event):
if event.user.id in self.users:
self.users[event.user.id].update(event.presence.user)
self.users[event.user.id].presence = event.presence
event.presence.user = self.users[event.user.id]
if event.guild_id not in self.guilds:
# Grab a copy of the user, and clear it out. All the operations below
# do not want the nested user object, as the normaly structure is
# user -> presence, and without clearing this becomes recursive
user = event.presence.user
user.presence = event.presence
event.presence.user = None
# if we have the user tracked locally, we can just use the presence
# update to update both their presence and the cached user object.
if user.id in self.users:
self.users[user.id].update(user)
else:
# Otherwise this user does not exist in our local cache, so we can
# use this opportunity to add them. They will quickly fall out of
# scope and be deleted if they aren't used below
self.users[user.id] = user
# Some updates come with a guild_id and roles the user is in, we should
# use this to update the guild member, but only if we have the guild
# cached.
if event.roles is UNSET or event.guild_id not in self.guilds:
return
if event.user.id not in self.guilds[event.guild_id].members:
if user.id not in self.guilds[event.guild_id].members:
return
self.guilds[event.guild_id].members[event.user.id].user.update(event.user)
self.guilds[event.guild_id].members[user.id].roles = event.roles

3
disco/types/guild.py

@ -9,7 +9,7 @@ from disco.util.functional import cached_property
from disco.types.base import (
SlottedModel, Field, ListField, AutoDictField, snowflake, text, binary, enum, datetime
)
from disco.types.user import User, Presence
from disco.types.user import User
from disco.types.voice import VoiceState
from disco.types.channel import Channel
from disco.types.message import Emoji
@ -300,7 +300,6 @@ class Guild(SlottedModel, Permissible):
emojis = AutoDictField(GuildEmoji, 'id')
voice_states = AutoDictField(VoiceState, 'session_id')
member_count = Field(int)
presences = ListField(Presence)
synced = Field(bool, default=False)

Loading…
Cancel
Save