add register

This commit is contained in:
Yuriy Yuriev
2026-05-14 18:23:50 +07:00
parent 7802bd3410
commit 328f510151
9 changed files with 312 additions and 233 deletions
+30 -17
View File
@@ -4,9 +4,10 @@
import asyncio
import os
import random
from collections import defaultdict
from dataclasses import dataclass, field
from typing import Optional, List, Dict
from typing import Optional, List, Dict, Set
from enum import Enum
import logging
@@ -119,7 +120,8 @@ class ProxyManager:
self._usage_count: Dict[str, int] = defaultdict(int)
self._cooldown_until: Dict[str, float] = {}
self._working_status: Dict[str, bool] = {}
self._used_ids: Set[str] = set()
self._load_proxies()
def _load_proxies(self) -> None:
@@ -159,59 +161,68 @@ class ProxyManager:
def _is_available(self, proxy: Proxy) -> bool:
"""Проверка доступности прокси."""
proxy_id = proxy.id
if proxy_id in self._in_use:
return False
if proxy_id in self._used_ids:
return False
if proxy_id in self._cooldown_until:
loop = asyncio.get_running_loop()
if loop.time() < self._cooldown_until[proxy_id]:
return False
del self._cooldown_until[proxy_id]
if self._usage_count[proxy_id] >= self.max_usage:
return False
return self._working_status.get(proxy_id, False)
async def acquire_proxy(self, timeout: float = 60) -> Optional[Proxy]:
"""Получает доступный прокси."""
if not self._proxies:
return None
loop = asyncio.get_running_loop()
start_time = loop.time()
attempt = 0
while True:
attempt += 1
async with self._lock:
available = [
p for p in self._proxies
if self._is_available(p)
]
if available:
proxy = min(available, key=lambda p: self._usage_count[p.id])
proxy = random.choice(available)
self._in_use[proxy.id] = asyncio.Event()
self._usage_count[proxy.id] += 1
self._used_ids.add(proxy.id)
logger.info(
f"Proxy acquired: {proxy.id} "
f"(type: {proxy.proxy_type.value}, "
f"used: {self._usage_count[proxy.id]}x)"
)
return proxy
all_used = len(self._used_ids) >= len(self._proxies)
if all_used:
logger.info("All proxies used once, resetting used list")
self._used_ids.clear()
logger.debug(f"No proxies available (attempt {attempt})")
elapsed = loop.time() - start_time
if elapsed >= timeout:
logger.warning(f"Proxy acquire timeout ({timeout}s)")
return None
await asyncio.sleep(1)
async def release_proxy(self, proxy: Proxy, success: bool = True) -> None:
@@ -256,11 +267,13 @@ class ProxyManager:
@property
def available_count(self) -> int:
loop = asyncio.get_running_loop()
now = loop.time()
working = sum(1 for s in self._working_status.values() if s)
in_use = len(self._in_use)
in_cooldown = sum(
1 for t in self._cooldown_until.values()
if asyncio.get_event_loop().time() < t
if now < t
)
return working - in_use - in_cooldown