From 476c160fd5c0632d25ad4025afa9a15425d4e7bf Mon Sep 17 00:00:00 2001 From: Yohan Boniface Date: Thu, 23 Jan 2025 17:05:13 +0100 Subject: [PATCH] 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 --- umap/sync/app.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/umap/sync/app.py b/umap/sync/app.py index caaca27b..27c52262 100644 --- a/umap/sync/app.py +++ b/umap/sync/app.py @@ -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())