fix (schedule): Fix potential deadlock.

This commit is contained in:
2023-07-08 09:30:10 +03:00
parent 043f358f57
commit d4154c5ce2
2 changed files with 12 additions and 4 deletions

View File

@@ -203,11 +203,15 @@ class ScheduleCog(LionCog):
Tuple of (slotid, guildid, userid) Tuple of (slotid, guildid, userid)
""" """
slotids = set(bookingid[0] for bookingid in bookingids) slotids = set(bookingid[0] for bookingid in bookingids)
locks = [self.slotlock(slotid) for slotid in slotids] logger.debug(
"Cancelling bookings: " + ', '.join(map(str, bookingids))
)
# Request all relevant slotlocks # Request all relevant slotlocks
await asyncio.gather(*(lock.acquire() for lock in locks)) locks = [self.slotlock(slotid) for slotid in sorted(slotids)]
try: try:
[await lock.acquire() for lock in locks]
# TODO: Some benchmarking here # TODO: Some benchmarking here
# Should we do the channel updates in bulk? # Should we do the channel updates in bulk?
for bookingid in bookingids: for bookingid in bookingids:
@@ -231,6 +235,9 @@ class ScheduleCog(LionCog):
finally: finally:
for lock in locks: for lock in locks:
lock.release() lock.release()
logger.info(
"Cancelled Scheduled Session bookings: " + ', '.join(map(str, bookingids))
)
return records return records
async def _cancel_booking_active(self, slotid, guildid, userid): async def _cancel_booking_active(self, slotid, guildid, userid):
@@ -404,9 +411,9 @@ class ScheduleCog(LionCog):
f"for slotids: {', '.join(map(str, slotids))}" f"for slotids: {', '.join(map(str, slotids))}"
) )
t = self.bot.translator.t t = self.bot.translator.t
locks = [self.slotlock(slotid) for slotid in slotids] locks = [self.slotlock(slotid) for slotid in sorted(slotids)]
await asyncio.gather(*(lock.acquire() for lock in locks))
try: try:
[await lock.acquire() for lock in locks]
# Validate bookings # Validate bookings
guild_data = await self.data.ScheduleGuild.fetch_or_create(guildid) guild_data = await self.data.ScheduleGuild.fetch_or_create(guildid)
config = ScheduleConfig(guildid, guild_data) config = ScheduleConfig(guildid, guild_data)

View File

@@ -178,6 +178,7 @@ class TimeSlot:
now = utc_now() now = utc_now()
tracker = self.bot.get_cog('VoiceTrackerCog') tracker = self.bot.get_cog('VoiceTrackerCog')
tracking_lock = tracker.tracking_lock tracking_lock = tracker.tracking_lock
sessions.sort(key=lambda s: s.guildid)
session_locks = [session.lock for session in sessions] session_locks = [session.lock for session in sessions]
# Take the tracking lock so that sessions are not started/finished while we reset the clock # Take the tracking lock so that sessions are not started/finished while we reset the clock