Spaces:
Running
Running
nacho commited on
Commit ·
f249601
1
Parent(s): f7df793
refactor: prelogin retry loop — 8 concurrent, 3min retry, infinite until all online
Browse files
main.py
CHANGED
|
@@ -381,24 +381,8 @@ async def import_accounts(request: Request, admin_key: str = Header(...)):
|
|
| 381 |
_save_settings(saved)
|
| 382 |
|
| 383 |
# 异步触发新导入账号的并行预登录
|
| 384 |
-
async def prelogin_new_accounts():
|
| 385 |
-
sem = asyncio.Semaphore(10) # 最多同时 10 个登录,避免浏览器启动过载
|
| 386 |
-
async def _login_one(account):
|
| 387 |
-
async with sem:
|
| 388 |
-
try:
|
| 389 |
-
logger.info("Pre-logging in newly imported account %s...", account.email)
|
| 390 |
-
await manager.get_or_create_browser_with_retry(
|
| 391 |
-
account, headless=config.browser.headless
|
| 392 |
-
)
|
| 393 |
-
logger.info("Pre-login OK: %s", account.email)
|
| 394 |
-
except Exception as e:
|
| 395 |
-
logger.error("Pre-login FAILED for %s: %s", account.email, e)
|
| 396 |
-
tasks = [_login_one(a) for a in new_accounts]
|
| 397 |
-
if tasks:
|
| 398 |
-
await asyncio.gather(*tasks, return_exceptions=True)
|
| 399 |
-
|
| 400 |
if new_accounts:
|
| 401 |
-
asyncio.create_task(
|
| 402 |
|
| 403 |
return {"success": True, "imported": imported, "total": len(manager.accounts)}
|
| 404 |
|
|
@@ -724,29 +708,58 @@ async def startup():
|
|
| 724 |
asyncio.create_task(_prelogin_all())
|
| 725 |
|
| 726 |
|
| 727 |
-
async def
|
| 728 |
-
"""并行
|
| 729 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 730 |
total = len(manager.accounts)
|
| 731 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 732 |
|
| 733 |
-
|
| 734 |
-
|
| 735 |
-
|
| 736 |
-
|
| 737 |
-
|
| 738 |
-
|
| 739 |
-
|
| 740 |
-
|
| 741 |
-
|
| 742 |
-
|
| 743 |
-
|
| 744 |
-
|
| 745 |
-
|
| 746 |
-
|
| 747 |
-
|
| 748 |
-
|
| 749 |
-
|
|
|
|
|
|
|
|
|
|
| 750 |
|
| 751 |
|
| 752 |
def main():
|
|
|
|
| 381 |
_save_settings(saved)
|
| 382 |
|
| 383 |
# 异步触发新导入账号的并行预登录
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 384 |
if new_accounts:
|
| 385 |
+
asyncio.create_task(_prelogin_loop(sem_size=8, retry_delay=180))
|
| 386 |
|
| 387 |
return {"success": True, "imported": imported, "total": len(manager.accounts)}
|
| 388 |
|
|
|
|
| 708 |
asyncio.create_task(_prelogin_all())
|
| 709 |
|
| 710 |
|
| 711 |
+
async def _prelogin_loop(sem_size=8, retry_delay=180):
|
| 712 |
+
"""通用预登录循环:并行登录一批账号,失败的在 delay 秒后重试,直到全部成功或错误过多。
|
| 713 |
+
|
| 714 |
+
参数:
|
| 715 |
+
sem_size: 最大同时登录数(默认 8)
|
| 716 |
+
retry_delay: 失败后重试等待秒数(默认 180 = 3 分钟)
|
| 717 |
+
"""
|
| 718 |
total = len(manager.accounts)
|
| 719 |
+
while True:
|
| 720 |
+
pending = [
|
| 721 |
+
(email, acc) for email, acc in manager.accounts.items()
|
| 722 |
+
if not acc.logged_in and acc.error_count < 5
|
| 723 |
+
]
|
| 724 |
+
if not pending:
|
| 725 |
+
logger.info("[prelogin] All accounts ready or max retries exhausted")
|
| 726 |
+
return
|
| 727 |
+
|
| 728 |
+
logger.info("[prelogin] %d/%d accounts pending, starting batch (concurrency=%d)...",
|
| 729 |
+
len(pending), total, sem_size)
|
| 730 |
+
sem = asyncio.Semaphore(sem_size)
|
| 731 |
+
|
| 732 |
+
async def _login_one(email, account):
|
| 733 |
+
async with sem:
|
| 734 |
+
try:
|
| 735 |
+
logger.info("[prelogin] %s ...", email)
|
| 736 |
+
await manager.get_or_create_browser_with_retry(
|
| 737 |
+
account, headless=config.browser.headless
|
| 738 |
+
)
|
| 739 |
+
logger.info("[prelogin OK] %s (muted=%s)", email, account.is_muted)
|
| 740 |
+
except Exception as e:
|
| 741 |
+
logger.error("[prelogin FAIL] %s: %s", email, e)
|
| 742 |
|
| 743 |
+
tasks = [_login_one(email, acc) for email, acc in pending]
|
| 744 |
+
if tasks:
|
| 745 |
+
await asyncio.gather(*tasks, return_exceptions=True)
|
| 746 |
+
|
| 747 |
+
still_pending = sum(
|
| 748 |
+
1 for a in manager.accounts.values()
|
| 749 |
+
if not a.logged_in and a.error_count < 5
|
| 750 |
+
)
|
| 751 |
+
if still_pending == 0:
|
| 752 |
+
logger.info("[prelogin] All done")
|
| 753 |
+
return
|
| 754 |
+
|
| 755 |
+
logger.info("[prelogin] %d accounts still pending, retrying in %ds...",
|
| 756 |
+
still_pending, retry_delay)
|
| 757 |
+
await asyncio.sleep(retry_delay)
|
| 758 |
+
|
| 759 |
+
|
| 760 |
+
async def _prelogin_all():
|
| 761 |
+
"""启动时后台预登录:同时 8 个,失败 3 分钟后重试,无限循环直到全部在线。"""
|
| 762 |
+
await _prelogin_loop(sem_size=8, retry_delay=180)
|
| 763 |
|
| 764 |
|
| 765 |
def main():
|