Skip to content

Add per-guild locking to prevent race conditions in concurrent config access#131

Draft
Claude wants to merge 2 commits intomainfrom
claude/fix-potential-race-conditions
Draft

Add per-guild locking to prevent race conditions in concurrent config access#131
Claude wants to merge 2 commits intomainfrom
claude/fix-potential-race-conditions

Conversation

@Claude
Copy link
Copy Markdown
Contributor

@Claude Claude AI commented Mar 28, 2026

Multiple cogs had race conditions where concurrent async operations could overwrite each other's config changes. When two tasks read → modify → write simultaneously, the second write would silently drop the first task's changes.

Changes

party/party.py

  • Add per-guild locks protecting party creation, editing, and user signup operations

secret_santa/secret_santa.py

  • Add per-guild locks protecting wishlist updates and event modifications

quotesdb/quotedb.py

  • Add per-guild locks protecting quote addition and deletion operations

assign_roles/assign_roles.py

  • Add per-guild locks protecting role authorization/deauthorization
  • Fix missing duplicate check: two concurrent authorizations could both pass the initial check and append duplicate entries

Implementation

Each cog now maintains a per-guild lock dictionary, following the pattern already used in albion_bandits:

def __init__(self, bot):
    self._config_locks = {}  # {guild_id: asyncio.Lock}
    
def _get_guild_lock(self, guild_id: int) -> asyncio.Lock:
    if guild_id not in self._config_locks:
        self._config_locks[guild_id] = asyncio.Lock()
    return self._config_locks[guild_id]

# Critical sections wrapped with lock before config context manager
async def operation(self, ctx, ...):
    lock = self._get_guild_lock(ctx.guild.id)
    async with lock:
        async with self.config.guild(ctx.guild).data() as data:
            # modify data

Locks are per-guild to avoid blocking operations across different servers. Each cog's config is modified independently under lock protection.

Implement application-level locking using asyncio.Lock for all four affected cogs:
- party: Lock party creation, editing, and user signup operations
- secret_santa: Lock wishlist updates and event modifications
- quotesdb: Lock quote addition and deletion operations
- assign_roles: Lock role authorization/deauthorization with duplicate check

Each cog now maintains per-guild locks to prevent concurrent config modifications
from overwriting each other. This follows the same pattern used in albion_bandits.

Agent-Logs-Url: https://github.com/psykzz/cogs/sessions/fcefea81-0cc1-4048-8aef-fb92d67b5155

Co-authored-by: psykzz <1134201+psykzz@users.noreply.github.com>
@Claude Claude AI changed the title [WIP] Fix potential race conditions in concurrent config access Add per-guild locking to prevent race conditions in concurrent config access Mar 28, 2026
@Claude Claude AI requested a review from psykzz March 28, 2026 10:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

⚠️ Potential race conditions in concurrent config access

2 participants