diff --git a/jarvis/cogs/extra/rolegiver.py b/jarvis/cogs/extra/rolegiver.py index 7ccd426..167b04a 100644 --- a/jarvis/cogs/extra/rolegiver.py +++ b/jarvis/cogs/extra/rolegiver.py @@ -42,6 +42,7 @@ class RolegiverCog(Extension): self.logger = logging.getLogger(__name__) self._group_cache: dict[int, dict[str, dict[str, int]]] = {} """`{GUILD_ID: {GROUP_NAME: {ROLE_NAME: ROLE_ID}}}`""" + self._cache_update_locks: dict[int, asyncio.Lock] = {} @listen() async def on_ready(self) -> None: @@ -95,12 +96,11 @@ class RolegiverCog(Extension): await rolegiver.save() await ctx.send(f"Rolegiver group {group} created!") - + if ctx.guild.id not in self._group_cache: self._group_cache[ctx.guild.id] = {rolegiver.group: {}} elif rolegiver.group not in self._group_cache[ctx.guild.id]: self._group_cache[ctx.guild.id][rolegiver.group] = {} - @rg_group.subcommand( sub_cmd_name="delete", sub_cmd_description="DDelete a rolegiver group" @@ -563,6 +563,7 @@ class RolegiverCog(Extension): @_rolegiver_list.autocomplete("group") async def _autocomplete_group(self, ctx: AutocompleteContext): groups = list(self._group_cache.get(ctx.guild.id, {}).keys()) + rolegivers = None if not groups: rolegivers = await Rolegiver.find(Rolegiver.guild == ctx.guild.id).to_list() groups = [r.group for r in rolegivers] @@ -570,6 +571,33 @@ class RolegiverCog(Extension): results = process.extract(ctx.input_text, groups, limit=5) choices = [{"name": r[0], "value": r[0]} for r in results] await ctx.send(choices) + if rolegivers: + await self._update_cache_from_autocomplete(ctx, rolegivers) + + async def _update_cache_from_autocomplete( + self, ctx: AutocompleteContext, rolegivers: list[Rolegiver] + ) -> None: + """Update the cache with a lock to prevent multiple simultaneous updates""" + lock = self._cache_update_locks.get(ctx.guild.id) + if not lock: + lock = asyncio.Lock() + self._cache_update_locks[ctx.guild.id] = lock + if not lock.locked(): + async with lock: + if ctx.guild.id not in self._group_cache: + self._group_cache[ctx.guild.id] = {} + for r in rolegivers: + roles = [] + for role_id in r.roles: + role = await ctx.guild.fetch_role(role_id) + if not role: + r.roles.remove(role_id) + continue + roles.append(role) + await r.save() + self._group_cache[ctx.guild.id][r.group] = { + role.name: role.role.id for role in roles + } def setup(bot: Client) -> None: