mirror of
https://github.com/willmiao/ComfyUI-Lora-Manager.git
synced 2026-03-26 07:35:44 -03:00
Refactor RecipeScanner to remove custom async timeout and streamline cache initialization
- Removed the custom async_timeout function and replaced it with direct usage of the initialization lock. - Simplified the cache initialization process by eliminating the dependency on the lora scanner. - Enhanced error handling during cache initialization to ensure a fallback to an empty cache on failure.
This commit is contained in:
@@ -15,21 +15,6 @@ from contextlib import asynccontextmanager
|
|||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
@asynccontextmanager
|
|
||||||
async def async_timeout(timeout: float):
|
|
||||||
task = asyncio.current_task()
|
|
||||||
loop = asyncio.get_running_loop()
|
|
||||||
handle = loop.call_later(timeout, task.cancel)
|
|
||||||
try:
|
|
||||||
yield
|
|
||||||
except asyncio.CancelledError:
|
|
||||||
raise asyncio.TimeoutError()
|
|
||||||
finally:
|
|
||||||
handle.cancel()
|
|
||||||
|
|
||||||
# Use native asyncio.timeout (Python 3.11+) if available, else use async_timeout.
|
|
||||||
_timeout = getattr(asyncio, "timeout", async_timeout)
|
|
||||||
|
|
||||||
class RecipeScanner:
|
class RecipeScanner:
|
||||||
"""Service for scanning and managing recipe images"""
|
"""Service for scanning and managing recipe images"""
|
||||||
|
|
||||||
@@ -80,61 +65,44 @@ class RecipeScanner:
|
|||||||
|
|
||||||
# Try to acquire the lock with a timeout to prevent deadlocks
|
# Try to acquire the lock with a timeout to prevent deadlocks
|
||||||
try:
|
try:
|
||||||
# Use a timeout for acquiring the lock
|
async with self._initialization_lock:
|
||||||
async with _timeout(1.0):
|
# Check again after acquiring the lock
|
||||||
async with self._initialization_lock:
|
if self._cache is not None and not force_refresh:
|
||||||
# Check again after acquiring the lock
|
return self._cache
|
||||||
if self._cache is not None and not force_refresh:
|
|
||||||
return self._cache
|
# Mark as initializing to prevent concurrent initializations
|
||||||
|
self._is_initializing = True
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Remove dependency on lora scanner initialization
|
||||||
|
# Scan for recipe data directly
|
||||||
|
raw_data = await self.scan_all_recipes()
|
||||||
|
|
||||||
# Mark as initializing to prevent concurrent initializations
|
# Update cache
|
||||||
self._is_initializing = True
|
self._cache = RecipeCache(
|
||||||
|
raw_data=raw_data,
|
||||||
|
sorted_by_name=[],
|
||||||
|
sorted_by_date=[]
|
||||||
|
)
|
||||||
|
|
||||||
try:
|
# Resort cache
|
||||||
# First ensure the lora scanner is initialized
|
await self._cache.resort()
|
||||||
if self._lora_scanner:
|
|
||||||
try:
|
|
||||||
lora_cache = await asyncio.wait_for(
|
|
||||||
self._lora_scanner.get_cached_data(),
|
|
||||||
timeout=10.0
|
|
||||||
)
|
|
||||||
except asyncio.TimeoutError:
|
|
||||||
logger.error("Timeout waiting for lora scanner initialization")
|
|
||||||
except Exception as e:
|
|
||||||
logger.error(f"Error waiting for lora scanner: {e}")
|
|
||||||
|
|
||||||
# Scan for recipe data
|
|
||||||
raw_data = await self.scan_all_recipes()
|
|
||||||
|
|
||||||
# Update cache
|
|
||||||
self._cache = RecipeCache(
|
|
||||||
raw_data=raw_data,
|
|
||||||
sorted_by_name=[],
|
|
||||||
sorted_by_date=[]
|
|
||||||
)
|
|
||||||
|
|
||||||
# Resort cache
|
|
||||||
await self._cache.resort()
|
|
||||||
|
|
||||||
return self._cache
|
|
||||||
|
|
||||||
except Exception as e:
|
return self._cache
|
||||||
logger.error(f"Recipe Manager: Error initializing cache: {e}", exc_info=True)
|
|
||||||
# Create empty cache on error
|
except Exception as e:
|
||||||
self._cache = RecipeCache(
|
logger.error(f"Recipe Manager: Error initializing cache: {e}", exc_info=True)
|
||||||
raw_data=[],
|
# Create empty cache on error
|
||||||
sorted_by_name=[],
|
self._cache = RecipeCache(
|
||||||
sorted_by_date=[]
|
raw_data=[],
|
||||||
)
|
sorted_by_name=[],
|
||||||
return self._cache
|
sorted_by_date=[]
|
||||||
finally:
|
)
|
||||||
# Mark initialization as complete
|
return self._cache
|
||||||
self._is_initializing = False
|
finally:
|
||||||
|
# Mark initialization as complete
|
||||||
|
self._is_initializing = False
|
||||||
|
|
||||||
except asyncio.TimeoutError:
|
|
||||||
# If we can't acquire the lock in time, return the current cache or an empty one
|
|
||||||
logger.warning("Timeout acquiring initialization lock - returning current cache state")
|
|
||||||
return self._cache or RecipeCache(raw_data=[], sorted_by_name=[], sorted_by_date=[])
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Unexpected error in get_cached_data: {e}")
|
logger.error(f"Unexpected error in get_cached_data: {e}")
|
||||||
return self._cache or RecipeCache(raw_data=[], sorted_by_name=[], sorted_by_date=[])
|
return self._cache or RecipeCache(raw_data=[], sorted_by_name=[], sorted_by_date=[])
|
||||||
@@ -464,4 +432,4 @@ class RecipeScanner:
|
|||||||
'total_pages': (total_items + page_size - 1) // page_size
|
'total_pages': (total_items + page_size - 1) // page_size
|
||||||
}
|
}
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|||||||
Reference in New Issue
Block a user