fix: add asyncio.Lock to get_browser() and deduplicate font-face blocks
All checks were successful
Build Docker Image / build (pull_request) Successful in 3m32s
All checks were successful
Build Docker Image / build (pull_request) Successful in 3m32s
Address two review findings from PR #94: 1. Race condition: concurrent requests could both launch Chromium when _browser is None. Wrap the init check in asyncio.Lock so only one coroutine creates the browser process. 2. Font duplication: the WOFF2 files are variable fonts covering all needed weights. Consolidate 5 @font-face blocks (3x Open Sans, 2x Source Sans 3) into 2 using CSS font-weight range syntax, saving ~163KB of redundant base64 per render. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
c262bb431e
commit
6ab50ba5f2
@ -9,6 +9,8 @@ from typing import Optional, List, Literal
|
|||||||
import logging
|
import logging
|
||||||
import pydantic
|
import pydantic
|
||||||
from pandas import DataFrame
|
from pandas import DataFrame
|
||||||
|
import asyncio as _asyncio
|
||||||
|
|
||||||
from playwright.async_api import async_playwright, Browser, Playwright
|
from playwright.async_api import async_playwright, Browser, Playwright
|
||||||
|
|
||||||
from ..card_creation import get_batter_card_data, get_pitcher_card_data
|
from ..card_creation import get_batter_card_data, get_pitcher_card_data
|
||||||
@ -37,6 +39,7 @@ from ..dependencies import oauth2_scheme, valid_token
|
|||||||
|
|
||||||
_browser: Browser | None = None
|
_browser: Browser | None = None
|
||||||
_playwright: Playwright | None = None
|
_playwright: Playwright | None = None
|
||||||
|
_browser_lock = _asyncio.Lock()
|
||||||
|
|
||||||
|
|
||||||
async def get_browser() -> Browser:
|
async def get_browser() -> Browser:
|
||||||
@ -45,18 +48,22 @@ async def get_browser() -> Browser:
|
|||||||
Reuses a single browser across all card renders, eliminating the ~1-1.5s
|
Reuses a single browser across all card renders, eliminating the ~1-1.5s
|
||||||
per-request launch/teardown overhead. Automatically reconnects if the
|
per-request launch/teardown overhead. Automatically reconnects if the
|
||||||
browser process has died.
|
browser process has died.
|
||||||
|
|
||||||
|
Uses an asyncio.Lock to prevent concurrent requests from racing to
|
||||||
|
launch multiple Chromium processes.
|
||||||
"""
|
"""
|
||||||
global _browser, _playwright
|
global _browser, _playwright
|
||||||
if _browser is None or not _browser.is_connected():
|
async with _browser_lock:
|
||||||
if _playwright is not None:
|
if _browser is None or not _browser.is_connected():
|
||||||
try:
|
if _playwright is not None:
|
||||||
await _playwright.stop()
|
try:
|
||||||
except Exception:
|
await _playwright.stop()
|
||||||
pass
|
except Exception:
|
||||||
_playwright = await async_playwright().start()
|
pass
|
||||||
_browser = await _playwright.chromium.launch(
|
_playwright = await async_playwright().start()
|
||||||
args=["--no-sandbox", "--disable-dev-shm-usage"]
|
_browser = await _playwright.chromium.launch(
|
||||||
)
|
args=["--no-sandbox", "--disable-dev-shm-usage"]
|
||||||
|
)
|
||||||
return _browser
|
return _browser
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user