Prevent concurrent rescans with async lock
- Add _scan_lock asyncio.Lock to AnimeService - Check if lock is held before starting rescan - Use async with to ensure lock is released on completion or exception - All 1024 tests passing
This commit is contained in:
parent
19cb8c11a0
commit
b6d44ca7d8
@ -17,7 +17,7 @@
|
|||||||
"keep_days": 30
|
"keep_days": 30
|
||||||
},
|
},
|
||||||
"other": {
|
"other": {
|
||||||
"master_password_hash": "$pbkdf2-sha256$29000$NkbIuZfSGiMEAGDMWau1tg$pMLf3tp4uH36YeG3KBgkX3F00dwbN2dGPQCWNvrjhnU",
|
"master_password_hash": "$pbkdf2-sha256$29000$1TrHeM8Z45yTsjZG6B1DKA$w4AoTXhgcGh90quXesvoRqVkH720fYXEu8LI2L4nUFM",
|
||||||
"anime_directory": "/mnt/server/serien/Serien/"
|
"anime_directory": "/mnt/server/serien/Serien/"
|
||||||
},
|
},
|
||||||
"version": "1.0.0"
|
"version": "1.0.0"
|
||||||
|
|||||||
24
data/config_backups/config_backup_20251224_210928.json
Normal file
24
data/config_backups/config_backup_20251224_210928.json
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
{
|
||||||
|
"name": "Aniworld",
|
||||||
|
"data_dir": "data",
|
||||||
|
"scheduler": {
|
||||||
|
"enabled": true,
|
||||||
|
"interval_minutes": 60
|
||||||
|
},
|
||||||
|
"logging": {
|
||||||
|
"level": "INFO",
|
||||||
|
"file": null,
|
||||||
|
"max_bytes": null,
|
||||||
|
"backup_count": 3
|
||||||
|
},
|
||||||
|
"backup": {
|
||||||
|
"enabled": false,
|
||||||
|
"path": "data/backups",
|
||||||
|
"keep_days": 30
|
||||||
|
},
|
||||||
|
"other": {
|
||||||
|
"master_password_hash": "$pbkdf2-sha256$29000$tTYmJCSEUArhnLN2TmktpQ$mhMKshEetPJfjRqYYUUvOGNRxcnIMNIto73IRKw4hPM",
|
||||||
|
"anime_directory": "/mnt/server/serien/Serien/"
|
||||||
|
},
|
||||||
|
"version": "1.0.0"
|
||||||
|
}
|
||||||
@ -56,6 +56,8 @@ class AnimeService:
|
|||||||
self._scan_total_items: int = 0
|
self._scan_total_items: int = 0
|
||||||
self._is_scanning: bool = False
|
self._is_scanning: bool = False
|
||||||
self._scan_current_directory: str = ""
|
self._scan_current_directory: str = ""
|
||||||
|
# Lock to prevent concurrent rescans
|
||||||
|
self._scan_lock = asyncio.Lock()
|
||||||
# Subscribe to SeriesApp events
|
# Subscribe to SeriesApp events
|
||||||
# Note: Events library uses assignment (=), not += operator
|
# Note: Events library uses assignment (=), not += operator
|
||||||
try:
|
try:
|
||||||
@ -482,7 +484,18 @@ class AnimeService:
|
|||||||
|
|
||||||
All series are identified by their 'key' (provider identifier),
|
All series are identified by their 'key' (provider identifier),
|
||||||
with 'folder' stored as metadata.
|
with 'folder' stored as metadata.
|
||||||
|
|
||||||
|
Note:
|
||||||
|
Only one scan can run at a time. If a scan is already in
|
||||||
|
progress, this method returns immediately without starting
|
||||||
|
a new scan.
|
||||||
"""
|
"""
|
||||||
|
# Check if a scan is already running (non-blocking)
|
||||||
|
if self._scan_lock.locked():
|
||||||
|
logger.info("Rescan already in progress, ignoring request")
|
||||||
|
return
|
||||||
|
|
||||||
|
async with self._scan_lock:
|
||||||
try:
|
try:
|
||||||
# Store event loop for event handlers
|
# Store event loop for event handlers
|
||||||
self._event_loop = asyncio.get_running_loop()
|
self._event_loop = asyncio.get_running_loop()
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user