修复Roundcube空URL和白名单重复同步
1. ROUNDCUBE_URL: os.getenv返回空字符串时不回退默认值,改为 or 默认值 2. ProxyFetcher: 缓存已同步白名单IP,后续线程跳过重复同步
This commit is contained in:
@@ -12,8 +12,8 @@ from loguru import logger
|
|||||||
import requests
|
import requests
|
||||||
|
|
||||||
|
|
||||||
# Roundcube Webmail 地址。可通过环境变量覆盖。
|
# Roundcube Webmail 地址。可通过环境变量覆盖。空值时回退到默认。
|
||||||
ROUNDCUBE_URL = os.getenv("MAIL_ROUNDCUBE_URL", "http://111.229.206.54:8000/")
|
ROUNDCUBE_URL = os.getenv("MAIL_ROUNDCUBE_URL") or "http://111.229.206.54:8000/"
|
||||||
|
|
||||||
|
|
||||||
class EmailVerifier:
|
class EmailVerifier:
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
"""简化版代理获取器(替代 ProxyManager)。
|
"""简化版代理获取器(替代 ProxyManager)。
|
||||||
|
|
||||||
专为短效代理设计:无池、无锁、无冷却、无复用。
|
专为短效代理设计:无池、无冷却、无复用。
|
||||||
每次调用 fetch_new_proxy() 从 API 取 1 个新代理,用完即弃。
|
每次调用 fetch_new_proxy() 从 API 取 1 个新代理,用完即弃。
|
||||||
|
|
||||||
线程安全:白名单同步由 ProxyResolver 内部的锁保证。
|
线程安全:白名单同步有全局锁 + IP缓存避免重复同步。
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
import threading
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
from loguru import logger
|
from loguru import logger
|
||||||
@@ -33,19 +34,35 @@ class ProxyFetcher:
|
|||||||
if _wl_credentials
|
if _wl_credentials
|
||||||
else None
|
else None
|
||||||
)
|
)
|
||||||
|
# 跨线程共享:已同步白名单的IP,避免5个线程重复同步同一个IP
|
||||||
|
self._synced_ip: Optional[str] = None
|
||||||
|
self._sync_lock = threading.Lock()
|
||||||
|
|
||||||
def fetch_new_proxy(self, max_attempts: int = 3) -> Optional[str]:
|
def fetch_new_proxy(self, max_attempts: int = 3) -> Optional[str]:
|
||||||
"""从代理 API 获取 1 个可用代理,失败返回 None。"""
|
"""从代理 API 获取 1 个可用代理,失败返回 None。"""
|
||||||
|
# 快速检查:是否已经同步过白名单
|
||||||
|
skip_sync = False
|
||||||
|
if self._whitelist_syncer:
|
||||||
|
with self._sync_lock:
|
||||||
|
if self._synced_ip:
|
||||||
|
skip_sync = True
|
||||||
|
|
||||||
resolver = ProxyResolver(
|
resolver = ProxyResolver(
|
||||||
api_url=self.api_url,
|
api_url=self.api_url,
|
||||||
whitelist_syncer=self._whitelist_syncer,
|
whitelist_syncer=self._whitelist_syncer,
|
||||||
sync_local_exit_ip=bool(self._whitelist_syncer),
|
sync_local_exit_ip=bool(self._whitelist_syncer) and not skip_sync,
|
||||||
sync_whitelist_once=False,
|
sync_whitelist_once=False,
|
||||||
)
|
)
|
||||||
result, msg = resolver.fetch_verified(
|
result, msg = resolver.fetch_verified(
|
||||||
max_attempts=max_attempts,
|
max_attempts=max_attempts,
|
||||||
return_all=False,
|
return_all=False,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# 记录已同步的IP
|
||||||
|
if self._whitelist_syncer and result:
|
||||||
|
with self._sync_lock:
|
||||||
|
self._synced_ip = self._synced_ip or "done"
|
||||||
|
|
||||||
if isinstance(result, str):
|
if isinstance(result, str):
|
||||||
logger.info(f"获取新代理: {result}")
|
logger.info(f"获取新代理: {result}")
|
||||||
return result
|
return result
|
||||||
|
|||||||
Reference in New Issue
Block a user