Added proper initialization control:

Setup lock in init.py to prevent concurrent cog loads
Check for existing cog instance to prevent duplicates
Setup_in_progress flag to track initialization state
Improved timeout handling and cleanup
Enhanced Queue Manager singleton pattern:
Class-level lock to prevent multiple instance creation
Consistent event naming with _init_event
Sequential component initialization
Proper lock ordering (global -> queue -> processing)
Improved state management:
Single source of truth for initialization state
Proper cleanup of resources on failure
Better error handling and logging
Timeout handling for all async operations
This commit is contained in:
pacnpal
2024-11-15 23:09:55 +00:00
parent 53e7769811
commit 39061cbf3e
2 changed files with 80 additions and 33 deletions

View File

@@ -7,29 +7,51 @@ from .exceptions import ProcessingError
logger = logging.getLogger("VideoArchiver")
# Global lock to prevent multiple concurrent setup attempts
_setup_lock = asyncio.Lock()
_setup_in_progress = False
async def setup(bot: Red) -> None:
"""Load VideoArchiver."""
try:
# Load main cog
cog = VideoArchiver(bot)
await bot.add_cog(cog)
# Wait for initialization to complete with timeout
global _setup_in_progress
# Use lock to prevent multiple concurrent setup attempts
async with _setup_lock:
try:
await asyncio.wait_for(cog.ready.wait(), timeout=30)
except asyncio.TimeoutError:
logger.error("VideoArchiver initialization timed out")
await bot.remove_cog(cog.__class__.__name__)
raise ProcessingError("Initialization timed out")
if not cog.ready.is_set():
logger.error("VideoArchiver failed to initialize")
await bot.remove_cog(cog.__class__.__name__)
raise ProcessingError("Initialization failed")
# Check if setup is already in progress
if _setup_in_progress:
logger.warning("VideoArchiver setup already in progress, skipping")
return
# Check if cog is already loaded
if "VideoArchiver" in bot.cogs:
logger.warning("VideoArchiver already loaded, skipping")
return
_setup_in_progress = True
except Exception as e:
logger.error(f"Failed to load VideoArchiver: {str(e)}")
raise
# Load main cog
cog = VideoArchiver(bot)
await bot.add_cog(cog)
# Wait for initialization to complete with timeout
try:
await asyncio.wait_for(cog.ready.wait(), timeout=30)
except asyncio.TimeoutError:
logger.error("VideoArchiver initialization timed out")
await bot.remove_cog(cog.__class__.__name__)
raise ProcessingError("Initialization timed out")
if not cog.ready.is_set():
logger.error("VideoArchiver failed to initialize")
await bot.remove_cog(cog.__class__.__name__)
raise ProcessingError("Initialization failed")
except Exception as e:
logger.error(f"Failed to load VideoArchiver: {str(e)}")
raise
finally:
_setup_in_progress = False
async def teardown(bot: Red) -> None:
"""Clean up when unloading."""