refactor: uv-based deps, no nexus auth, LLM retries, lock cleanup, health checks, e2e tests

This commit is contained in:
Marker689
2026-05-11 19:27:56 +03:00
parent 698f02c8af
commit 04abe44ab4
20 changed files with 1583 additions and 51 deletions

View File

@@ -28,6 +28,18 @@ _url_lock = asyncio.Lock()
# Global semaphore to limit concurrent GuardDog processes
_scan_semaphore = asyncio.Semaphore(config.max_concurrent_scans)
# Cleanup interval for unused locks (30 minutes)
_LOCK_CLEANUP_INTERVAL = 1800
async def _cleanup_url_locks():
"""Periodically clean up unused URL locks to prevent memory leaks."""
while True:
await asyncio.sleep(_LOCK_CLEANUP_INTERVAL)
for key in list(_url_locks.keys()):
if not _url_locks[key].locked():
_url_locks.pop(key, None)
async def harvest(
download_url: str,
@@ -94,6 +106,7 @@ async def harvest(
await session.commit()
await session.refresh(scan)
tmpdir = None
try:
await asyncio.to_thread(os.makedirs, config.temp_dir, exist_ok=True)
tmpdir = await asyncio.to_thread(tempfile.mkdtemp, dir=config.temp_dir)
@@ -201,7 +214,8 @@ async def harvest(
return scan
finally:
await asyncio.to_thread(shutil.rmtree, tmpdir, ignore_errors=True)
if tmpdir:
await asyncio.to_thread(shutil.rmtree, tmpdir, ignore_errors=True)
async def _run_llm_analysis(findings: list[Finding], session: AsyncSession) -> list[dict]: