fix: harden token pools and CPA export

This commit is contained in:
github-actions[bot]
2026-07-14 13:43:54 +00:00
parent 6f799e19ce
commit 286a0f1734
11 changed files with 210 additions and 767 deletions
+55 -8
View File
@@ -189,10 +189,11 @@ def create_standalone_page(proxy: Optional[str] = None, headless: bool = False,
pass
break
from .proxyutil import proxy_for_chromium, proxy_log_label, resolve_proxy
from .proxyutil import prepare_chromium_proxy, proxy_log_label, resolve_proxy
resolved = resolve_proxy(proxy)
chrome_proxy = proxy_for_chromium(resolved)
proxy_bridge = None
chrome_proxy, proxy_bridge = prepare_chromium_proxy(resolved, log=logger)
if chrome_proxy:
options.set_argument("--proxy-server=%s" % chrome_proxy)
logger("browser proxy=%s (chromium %s)" % (proxy_log_label(resolved), chrome_proxy))
@@ -200,19 +201,50 @@ def create_standalone_page(proxy: Optional[str] = None, headless: bool = False,
logger("browser proxy=(none)")
browser = Chromium(options)
if proxy_bridge is not None:
try:
setattr(browser, "_cpa_proxy_bridge", proxy_bridge)
except Exception:
pass
_register_mint_browser(browser)
page = browser.latest_tab
logger("standalone chromium started")
return browser, page
def close_standalone(browser: Any) -> None:
if browser is None:
return
_unregister_mint_browser(browser)
bridge = getattr(browser, "_cpa_proxy_bridge", None)
try:
browser.quit()
except Exception:
pass
if bridge is not None:
try:
bridge.stop()
except Exception:
pass
_mint_tls = threading.local()
_mint_registry_lock = threading.Lock()
_mint_registry = set()
def _register_mint_browser(browser: Any) -> None:
if browser is None:
return
with _mint_registry_lock:
_mint_registry.add(browser)
def _unregister_mint_browser(browser: Any) -> None:
if browser is None:
return
with _mint_registry_lock:
_mint_registry.discard(browser)
def _mint_tls_get():
@@ -417,8 +449,9 @@ def release_mint_browser(owned: bool, success: bool, log: Optional[LogFn] = None
def shutdown_mint_browsers() -> None:
state = _mint_tls_get()
browser = state.get("browser")
if browser is not None:
with _mint_registry_lock:
browsers = list(_mint_registry)
for browser in browsers:
try:
close_standalone(browser)
except Exception:
@@ -824,7 +857,7 @@ def mint_with_browser(
session = request_device_code(proxy=resolved or None)
last_error = None
break
except BaseException as exc:
except Exception as exc:
last_error = exc
logger("request_device_code attempt %s/3 failed: %s" % (attempt, exc))
_sleep(1.5 * attempt)
@@ -852,22 +885,28 @@ def mint_with_browser(
token_box = {}
error_box = {}
def combined_cancel():
return stop_event.is_set() or bool(cancel and cancel())
def _poll() -> None:
try:
time.sleep(2)
for _ in range(20):
if combined_cancel():
raise OAuthDeviceError("cancelled")
time.sleep(0.1)
result = poll_device_token(
session.device_code,
token_endpoint=session.token_endpoint,
interval=max(session.interval, 5),
expires_in=min(session.expires_in, int(browser_timeout_sec) + 60),
log=logger,
cancel=cancel,
cancel=combined_cancel,
proxy=resolved or None,
)
token_box["token"] = result
stop_event.set()
logger("token poll SUCCESS — stop_event set")
except BaseException as exc:
except Exception as exc:
error_box["err"] = exc
stop_event.set()
@@ -897,8 +936,16 @@ def mint_with_browser(
)
if hard:
stop_event.set()
thread.join(timeout=5)
if thread.is_alive():
logger("token poll thread did not stop within 5s after browser failure")
raise
thread.join(timeout=max(browser_timeout_sec, 60) + 30)
if thread.is_alive():
stop_event.set()
thread.join(timeout=5)
if thread.is_alive():
raise OAuthDeviceError("token poll thread did not stop after timeout")
if "token" in token_box:
token_result = token_box["token"]
success = True