Fixed proxy crash: removed asyncio.Lock (cross-thread event loop issue)
This commit is contained in:
15
proxy.py
15
proxy.py
@@ -82,14 +82,12 @@ class ProxyEntry:
|
|||||||
class ProxyManager:
|
class ProxyManager:
|
||||||
"""
|
"""
|
||||||
Manages a dynamic list of proxies with fetching, testing, rotation.
|
Manages a dynamic list of proxies with fetching, testing, rotation.
|
||||||
Thread-safe for use across asyncio event loops.
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.proxies: List[ProxyEntry] = []
|
self.proxies: List[ProxyEntry] = []
|
||||||
self._working: List[ProxyEntry] = []
|
self._working: List[ProxyEntry] = []
|
||||||
self._rotation_index = 0
|
self._rotation_index = 0
|
||||||
self._lock = asyncio.Lock()
|
|
||||||
|
|
||||||
# State
|
# State
|
||||||
self.enabled = False
|
self.enabled = False
|
||||||
@@ -127,7 +125,6 @@ class ProxyManager:
|
|||||||
Fetch proxy lists from all configured sources.
|
Fetch proxy lists from all configured sources.
|
||||||
Returns total number of unique proxies collected.
|
Returns total number of unique proxies collected.
|
||||||
"""
|
"""
|
||||||
async with self._lock:
|
|
||||||
if self.fetching:
|
if self.fetching:
|
||||||
return len(self.proxies)
|
return len(self.proxies)
|
||||||
self.fetching = True
|
self.fetching = True
|
||||||
@@ -191,7 +188,6 @@ class ProxyManager:
|
|||||||
return len(self.proxies)
|
return len(self.proxies)
|
||||||
|
|
||||||
finally:
|
finally:
|
||||||
async with self._lock:
|
|
||||||
self.fetching = False
|
self.fetching = False
|
||||||
|
|
||||||
def _parse_proxifly_json(self, text: str) -> List[Tuple[str, int, str]]:
|
def _parse_proxifly_json(self, text: str) -> List[Tuple[str, int, str]]:
|
||||||
@@ -294,7 +290,6 @@ class ProxyManager:
|
|||||||
Test all untested/failed proxies in the pool.
|
Test all untested/failed proxies in the pool.
|
||||||
Returns number of working proxies found.
|
Returns number of working proxies found.
|
||||||
"""
|
"""
|
||||||
async with self._lock:
|
|
||||||
if self.testing:
|
if self.testing:
|
||||||
return self.working_count
|
return self.working_count
|
||||||
self.testing = True
|
self.testing = True
|
||||||
@@ -338,7 +333,6 @@ class ProxyManager:
|
|||||||
return self.working_count
|
return self.working_count
|
||||||
|
|
||||||
finally:
|
finally:
|
||||||
async with self._lock:
|
|
||||||
self.testing = False
|
self.testing = False
|
||||||
|
|
||||||
# ── ROTATION ──────────────────────────────────────────────────────────
|
# ── ROTATION ──────────────────────────────────────────────────────────
|
||||||
@@ -348,7 +342,6 @@ class ProxyManager:
|
|||||||
Get the next working proxy (round-robin if auto_rotate is enabled).
|
Get the next working proxy (round-robin if auto_rotate is enabled).
|
||||||
Returns None if no working proxies available.
|
Returns None if no working proxies available.
|
||||||
"""
|
"""
|
||||||
async with self._lock:
|
|
||||||
if not self._working:
|
if not self._working:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@@ -380,16 +373,9 @@ class ProxyManager:
|
|||||||
|
|
||||||
Returns (reader, writer) - same as asyncio.open_connection.
|
Returns (reader, writer) - same as asyncio.open_connection.
|
||||||
"""
|
"""
|
||||||
retry_depth = int(kwargs.pop("_proxy_retry_depth", 0))
|
|
||||||
max_proxy_retries = 32
|
|
||||||
|
|
||||||
if not self.enabled:
|
if not self.enabled:
|
||||||
return await asyncio.open_connection(host, port, **kwargs)
|
return await asyncio.open_connection(host, port, **kwargs)
|
||||||
|
|
||||||
if retry_depth >= max_proxy_retries:
|
|
||||||
logger.debug("Proxy retry limit reached, using direct connection")
|
|
||||||
return await asyncio.open_connection(host, port, **kwargs)
|
|
||||||
|
|
||||||
proxy = await self.get_proxy()
|
proxy = await self.get_proxy()
|
||||||
if proxy is None:
|
if proxy is None:
|
||||||
# No working proxy — fallback to direct
|
# No working proxy — fallback to direct
|
||||||
@@ -410,7 +396,6 @@ class ProxyManager:
|
|||||||
self.mark_bad(proxy)
|
self.mark_bad(proxy)
|
||||||
# Retry with next proxy
|
# Retry with next proxy
|
||||||
logger.debug(f"Proxy {proxy} failed: {e}, trying next...")
|
logger.debug(f"Proxy {proxy} failed: {e}, trying next...")
|
||||||
kwargs["_proxy_retry_depth"] = retry_depth + 1
|
|
||||||
return await self.open_connection(host, port, **kwargs)
|
return await self.open_connection(host, port, **kwargs)
|
||||||
|
|
||||||
# ── STATS ─────────────────────────────────────────────────────────────
|
# ── STATS ─────────────────────────────────────────────────────────────
|
||||||
|
|||||||
Reference in New Issue
Block a user