refactor(backend): optimize database safety, validator performance, and scheduler concurrency

- Fix SQL injection risks in proxy_repo and task_repo
- Atomic acquire_pending with UPDATE ... RETURNING
- Reuse aiohttp ClientSession in ValidatorService
- Replace polling with asyncio.Event in SchedulerService
- Optimize ValidationQueue.drain with asyncio.Condition
- Concurrent plugin crawling with asyncio.gather
- Unify ProxyRaw model import path
- Fix test baseline and remove tracked __pycache__ files
This commit is contained in:
祀梦
2026-04-04 14:43:31 +08:00
parent abb8b32ed3
commit 635c524a7e
27 changed files with 103 additions and 89 deletions

View File

@@ -20,12 +20,14 @@ class SchedulerService:
self.proxy_repo = proxy_repo
self.interval_minutes = 30
self.running = False
self._stop_event = asyncio.Event()
self._task: asyncio.Task | None = None
async def start(self):
if self.running:
logger.warning("Scheduler already running")
return
self._stop_event.clear()
self.running = True
await self.validation_queue.start()
self._task = asyncio.create_task(self._run_loop())
@@ -33,6 +35,7 @@ class SchedulerService:
async def stop(self):
self.running = False
self._stop_event.set()
if self._task:
self._task.cancel()
try:
@@ -55,10 +58,10 @@ class SchedulerService:
except Exception as e:
logger.error(f"Scheduler loop error: {e}")
# 等待下一次
for _ in range(self.interval_minutes * 60):
if not self.running:
break
await asyncio.sleep(1)
try:
await asyncio.wait_for(self._stop_event.wait(), timeout=self.interval_minutes * 60)
except asyncio.TimeoutError:
pass
async def _do_validate_all(self):
"""验证数据库中所有存量代理"""