fix: prevent browser process leaks and improve robustness
- fix(browser): wrap context lifecycle in try/finally to ensure browser closes on exceptions and KeyboardInterrupt (login, sniffer, generator) - fix(browser): replace time.sleep with Playwright native waits (wait_for, wait_for_timeout) for more reliable element interaction - fix(browser): use parameterized page.evaluate instead of f-string JS injection in generator polling - fix(api): add retry logic in wait_for_completion to survive transient network errors - fix(config): add prepare_profile_dir to copy profile to temp dir, preventing Chromium SingletonLock conflicts when tools run concurrently - fix(sniffer): stream API logs to tempfile instead of unbounded memory list to avoid OOM - fix(api): specify encoding='utf-8' when loading cookies from file Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,8 @@
|
||||
import os
|
||||
import shutil
|
||||
import tempfile
|
||||
from pathlib import Path
|
||||
from typing import Optional, Tuple
|
||||
|
||||
|
||||
def get_config_dir() -> Path:
|
||||
@@ -21,3 +24,21 @@ def get_profile_dir() -> Path:
|
||||
path = get_config_dir() / "profile"
|
||||
path.mkdir(parents=True, exist_ok=True)
|
||||
return path
|
||||
|
||||
|
||||
def prepare_profile_dir() -> Tuple[str, Optional[str]]:
|
||||
"""
|
||||
将标准 profile 复制到临时目录,避免 Chromium 锁冲突。
|
||||
|
||||
Returns:
|
||||
(实际使用的 profile 路径, 临时目录路径或 None)。
|
||||
如果使用了临时副本,调用者应在完成后用 shutil.rmtree 删除。
|
||||
"""
|
||||
standard = str(get_profile_dir())
|
||||
if not os.path.exists(standard):
|
||||
return standard, None
|
||||
|
||||
temp_root = tempfile.mkdtemp(prefix="hunyuan3dweb-profile-")
|
||||
temp_profile = os.path.join(temp_root, "profile")
|
||||
shutil.copytree(standard, temp_profile, dirs_exist_ok=True)
|
||||
return temp_profile, temp_root
|
||||
|
||||
Reference in New Issue
Block a user