总结优化

This commit is contained in:
liuwei
2026-03-11 11:32:27 +08:00
parent 4555f9eb69
commit cfabd169fb

View File

@@ -2,42 +2,54 @@ import subprocess
import time
import markdown
from pathlib import Path
import psutil
from playwright.async_api import async_playwright
import os
import asyncio
from loguru import logger
async def safe_close_browser(browser, timeout: float = 5.0) -> None:
async def safe_close_browser(browser, timeout: float = 4.0) -> None:
if not browser:
return
# Close contexts first to reduce hanging risk.
try:
for ctx in browser.contexts:
# 1. 先尝试关闭所有 page最重要
for context in browser.contexts[:]: # 复制列表防止修改中迭代
for page in context.pages[:]:
try:
await asyncio.wait_for(ctx.close(), timeout=timeout)
except Exception:
await asyncio.wait_for(page.close(), timeout=1.5)
except:
pass
except Exception:
pass
try:
await asyncio.wait_for(context.close(), timeout=timeout)
except:
pass
# Then close browser with timeout.
# 2. 尝试优雅关闭 browser
try:
await asyncio.wait_for(browser.close(), timeout=timeout)
logger.debug("browser closed gracefully")
return
except asyncio.TimeoutError:
logger.warning("Browser close timed out, killing process")
except Exception as e:
logger.warning(f"Browser close failed, killing process: {e}")
except (asyncio.TimeoutError, Exception) as e:
logger.warning(f"browser.close failed: {e}")
# Final fallback: kill underlying process.
try:
proc = browser.process
if proc:
proc.kill()
except Exception:
pass
# 3. 强制杀进程树(最关键一步)
if browser.process and browser.process.pid:
try:
parent = psutil.Process(browser.process.pid)
children = parent.children(recursive=True)
for child in children:
try:
child.kill()
except psutil.NoSuchProcess:
pass
parent.kill()
# 可选:等待一小会儿确认退出
psutil.wait_procs([parent] + children, timeout=3)
logger.debug("process tree killed")
except (psutil.NoSuchProcess, Exception) as e:
logger.warning(f"force kill failed: {e}")
# ================= 样式与 HTML 处理 =================