Improve BrowserLauncher cleanup handling

This commit is contained in:
程序员阿江-Relakkes
2025-09-26 16:52:38 +08:00
parent 7b9db2f748
commit 3237073a0e
2 changed files with 69 additions and 27 deletions

View File

@@ -14,6 +14,7 @@ import platform
import subprocess
import time
import socket
import signal
from typing import Optional, List, Tuple
import asyncio
from pathlib import Path
@@ -106,7 +107,7 @@ class BrowserLauncher:
raise RuntimeError(f"无法找到可用的端口,已尝试 {start_port}{port-1}")
def launch_browser(self, browser_path: str, debug_port: int, headless: bool = False,
def launch_browser(self, browser_path: str, debug_port: int, headless: bool = False,
user_data_dir: Optional[str] = None) -> subprocess.Popen:
"""
启动浏览器进程
@@ -169,7 +170,8 @@ class BrowserLauncher:
stderr=subprocess.DEVNULL,
preexec_fn=os.setsid # 创建新的进程组
)
self.browser_process = process
return process
except Exception as e:
@@ -230,20 +232,48 @@ class BrowserLauncher:
"""
清理资源,关闭浏览器进程
"""
if self.browser_process:
try:
utils.logger.info("[BrowserLauncher] 正在关闭浏览器进程...")
if self.system == "Windows":
# Windows下使用taskkill强制终止进程树
subprocess.run(["taskkill", "/F", "/T", "/PID", str(self.browser_process.pid)],
capture_output=True)
if not self.browser_process:
return
process = self.browser_process
if process.poll() is not None:
utils.logger.info("[BrowserLauncher] 浏览器进程已退出,无需清理")
self.browser_process = None
return
utils.logger.info("[BrowserLauncher] 正在关闭浏览器进程...")
try:
if self.system == "Windows":
# 先尝试正常终止
process.terminate()
try:
process.wait(timeout=5)
except subprocess.TimeoutExpired:
utils.logger.warning("[BrowserLauncher] 正常终止超时使用taskkill强制结束")
subprocess.run(
["taskkill", "/F", "/T", "/PID", str(process.pid)],
capture_output=True,
check=False,
)
process.wait(timeout=5)
else:
pgid = os.getpgid(process.pid)
try:
os.killpg(pgid, signal.SIGTERM)
except ProcessLookupError:
utils.logger.info("[BrowserLauncher] 浏览器进程组不存在,可能已退出")
else:
# Unix系统下终止进程组
os.killpg(os.getpgid(self.browser_process.pid), 9)
self.browser_process = None
utils.logger.info("[BrowserLauncher] 浏览器进程已关闭")
except Exception as e:
utils.logger.warning(f"[BrowserLauncher] 关闭浏览器进程时出错: {e}")
try:
process.wait(timeout=5)
except subprocess.TimeoutExpired:
utils.logger.warning("[BrowserLauncher] 优雅关闭超时发送SIGKILL")
os.killpg(pgid, signal.SIGKILL)
process.wait(timeout=5)
utils.logger.info("[BrowserLauncher] 浏览器进程已关闭")
except Exception as e:
utils.logger.warning(f"[BrowserLauncher] 关闭浏览器进程时出错: {e}")
finally:
self.browser_process = None

View File

@@ -291,16 +291,28 @@ class CDPBrowserManager:
"""
try:
# 关闭浏览器上下文
# if self.browser_context:
# await self.browser_context.close()
# self.browser_context = None
# utils.logger.info("[CDPBrowserManager] 浏览器上下文已关闭")
if self.browser_context:
try:
await self.browser_context.close()
utils.logger.info("[CDPBrowserManager] 浏览器上下文已关闭")
except Exception as context_error:
utils.logger.warning(
f"[CDPBrowserManager] 关闭浏览器上下文失败: {context_error}"
)
finally:
self.browser_context = None
# # 断开浏览器连接
# if self.browser:
# await self.browser.close()
# self.browser = None
# utils.logger.info("[CDPBrowserManager] 浏览器连接已断开")
# 断开浏览器连接
if self.browser:
try:
await self.browser.close()
utils.logger.info("[CDPBrowserManager] 浏览器连接已断开")
except Exception as browser_error:
utils.logger.warning(
f"[CDPBrowserManager] 关闭浏览器连接失败: {browser_error}"
)
finally:
self.browser = None
# 关闭浏览器进程(如果配置为自动关闭)
if config.AUTO_CLOSE_BROWSER: