wip(sync): clean stale username from redis

We wanted to use the HEXPIRE command, but discovered that this command
is only available since the Redis 7.4 version (the latest), and this version
does not have an OSI compliant licence, so it is generally not installable
through common packages managers. The OSS fork is Valkey, but it still does
not have the HEXPIRE command.

So we decide to clean those keys manually, and in order no do this clean
task at each websocket connection, we only do it when we are the first user
to connect to a given map.

Co-authored-by: David Larlet <david@larlet.fr>
This commit is contained in:
Yohan Boniface 2025-01-23 17:05:13 +01:00
parent 0d5e3047f4
commit 476c160fd5

View file

@ -69,12 +69,20 @@ class Peer:
async def get_peers(self):
known = await self.client.hgetall(self.room_key)
active = await self.client.pubsub_channels(f"user:{self.map_id}:*")
if not active:
# Poor man way of deleting stale usernames from the store
# HEXPIRE command is not in the open source Redis version
await self.client.delete(self.room_key)
await self.store_username()
active = [name.split(b":")[-1] for name in active]
if self.peer_id.encode() not in active:
# Our connection may not yet be active
active.append(self.peer_id.encode())
return {k: v for k, v in known.items() if k in active}
async def store_username(self):
await self.client.hset(self.room_key, self.peer_id, self.username)
async def listen_to_channel(self, channel_name):
async def reader(pubsub):
await pubsub.subscribe(channel_name)
@ -136,7 +144,7 @@ class Peer:
self.peer_id = message.peer
self.username = message.username
print("AUTHENTICATED", self.peer_id)
await self.client.hset(self.room_key, self.peer_id, self.username)
await self.store_username()
await self.listen()
response = JoinResponse(peer=self.peer_id, peers=await self.get_peers())
await self.send(response.model_dump_json())