Studio: stop hint, Uvicorn log rename, reachability check + Mac UI CI retry hardening (#5503)
* Studio: clearer stop hint, Uvicorn log rename, external reachability check
Three startup-banner UX improvements to make it obvious how to stop
Studio, what the externally reachable URL really is, and whether that
URL actually works from outside.
1. Stop hint at the end of the banner
* Bright orange "To stop Unsloth Studio: press Ctrl+C in this
terminal." line, with a dim "(On macOS this is Control+C, not
Command+C.)" follow-up so the macOS Cmd-vs-Ctrl confusion is
headed off.
* When bound to 127.0.0.1, an extra "To deploy and access globally"
block tells the user the exact relaunch command
(unsloth studio -H 0.0.0.0 -p PORT) with a trusted-networks
caveat.
2. Uvicorn startup log rewrite
* Installs a stdlib logging.Filter on the uvicorn / uvicorn.error
loggers that:
- renames the prefix to "Unsloth Studio running on"
- swaps the wildcard bind for the resolved external host so the
line agrees with the banner
- replaces "(Press CTRL+C to quit)" with the same Mac-aware
stop hint
* Rewrites both record.msg and record.color_message so it works
under plain and colorized log formatters.
3. External reachability self-test on wildcard binds
* Synchronous probe via check-host.net's TCP JSON API confirms
whether the advertised public URL actually accepts connections
from the internet.
* On failure prints the resolved IP, the failing-node count, the
usual causes (AWS SG, GCP firewall rule, Azure NSG, home router),
and an SSH local-forward workaround.
* Verifies 127.0.0.1 / ::1 first and only offers a local fallback
URL when loopback actually responds, so we never claim a port
works when it does not.
* Private / loopback / link-local display hosts short-circuit with
a one-line LAN note instead of a probe.
* Bounded at roughly 15 seconds, early-exits on two decisive node
results, all failures swallowed.
Banner is split into print_studio_access_banner(include_stop_hint=...)
plus a new print_studio_stop_hint() so the reachability output can be
sandwiched between the URL section and the stop hint, keeping the
stop hint as the last text on screen.
Pure stdlib (socket, urllib, ipaddress, logging, threading), no new
dependencies, identical behavior on Linux, macOS, and Windows.
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* CI: harden Mac Studio UI tests against Chromium ERR_NO_BUFFER_SPACE
The Mac Studio UI workflow already retries the Playwright scripts on
the racy 'Unexpected end of JSON input' pipeTransport crash, but
falls through on ERR_NO_BUFFER_SPACE -- a separate Chromium failure
that fires when the macos-14 free-runner kernel briefly runs out of
socket buffers. Same fix shape, two layers:
* In-script: when a change-password page.goto() attempt fails with
ERR_NO_BUFFER_SPACE, sleep 5s then 15s before the next attempt so
the OS has time to recover socket buffers. Other failures retry
immediately as before.
* Workflow: extend both Playwright retry blocks (chat-ui and
extra-ui) to also trigger the full Studio kill + reset + reboot
retry on ERR_NO_BUFFER_SPACE, not just on the pipeTransport JSON
crash.
Real assertion / timeout failures still bypass retry and surface
immediately. Linux and Windows workflows are unchanged; the flake
is macOS-runner-specific.
---------
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
This commit is contained in:
parent
77c8d80a85
commit
b59e02e977
5 changed files with 374 additions and 20 deletions
34
.github/workflows/studio-mac-ui-smoke.yml
vendored
34
.github/workflows/studio-mac-ui-smoke.yml
vendored
|
|
@ -183,16 +183,16 @@ jobs:
|
|||
# available to llama.cpp from CI; gemma-3-270m turn latency
|
||||
# has been observed to crowd the 180s default. Triple it.
|
||||
STUDIO_UI_TURN_TIMEOUT_MS: '540000'
|
||||
# Retry up to 3 times to absorb the racy Playwright Node 24
|
||||
# pipeTransport.js 'Unexpected end of JSON input' crash that
|
||||
# fires intermittently on macos-14 free runners (Chromium
|
||||
# browser process dies mid-test → driver Node process can't
|
||||
# parse the truncated JSON-RPC line and exits). The retry
|
||||
# FULLY resets Studio (kill, reset-password, reboot, wait
|
||||
# /api/health, re-export bootstrap pw) before re-running the
|
||||
# script so the change-password flow finds a fresh bootstrap.
|
||||
# A real test failure (assertion / timeout) does NOT match the
|
||||
# JSON pattern so it bypasses retry and surfaces immediately.
|
||||
# Retry up to 3 times to absorb known macos-14 free-runner
|
||||
# flakes: (1) Playwright Node 24 pipeTransport.js 'Unexpected
|
||||
# end of JSON input' crash when the Chromium browser process
|
||||
# dies mid-test, and (2) Chromium net::ERR_NO_BUFFER_SPACE
|
||||
# when the runner's kernel briefly runs out of socket buffers.
|
||||
# The retry FULLY resets Studio (kill, reset-password, reboot,
|
||||
# wait /api/health, re-export bootstrap pw) before re-running
|
||||
# the script. A real test failure (assertion / timeout) does
|
||||
# NOT match either pattern so it bypasses retry and surfaces
|
||||
# immediately.
|
||||
run: |
|
||||
mkdir -p logs/playwright
|
||||
attempt=1
|
||||
|
|
@ -205,9 +205,10 @@ jobs:
|
|||
if [ "$rc" -eq 0 ]; then
|
||||
break
|
||||
fi
|
||||
if grep -q "Unexpected end of JSON input" logs/playwright_attempt_${attempt}.log \
|
||||
if { grep -q "Unexpected end of JSON input" logs/playwright_attempt_${attempt}.log \
|
||||
|| grep -q "ERR_NO_BUFFER_SPACE" logs/playwright_attempt_${attempt}.log; } \
|
||||
&& [ "$attempt" -lt "$max_attempts" ]; then
|
||||
echo "::warning::Playwright pipeTransport JSON crash on attempt ${attempt}; resetting Studio and retrying..."
|
||||
echo "::warning::Playwright flake on attempt ${attempt}; resetting Studio and retrying..."
|
||||
kill "${STUDIO_PID}" 2>/dev/null || true
|
||||
sleep 2
|
||||
unsloth studio reset-password
|
||||
|
|
@ -280,8 +281,8 @@ jobs:
|
|||
STUDIO_UI_TURN_TIMEOUT_MS: '540000'
|
||||
GGUF_REPO: ${{ env.GGUF_REPO }}
|
||||
GGUF_VARIANT: ${{ env.GGUF_VARIANT }}
|
||||
# Same pipeTransport JSON-crash retry shape as "Drive the chat
|
||||
# UI with Playwright" -- see comment there.
|
||||
# Same flake-retry shape as "Drive the chat UI with Playwright"
|
||||
# -- catches pipeTransport JSON crash and ERR_NO_BUFFER_SPACE.
|
||||
run: |
|
||||
mkdir -p logs/playwright_extra
|
||||
attempt=1
|
||||
|
|
@ -294,9 +295,10 @@ jobs:
|
|||
if [ "$rc" -eq 0 ]; then
|
||||
break
|
||||
fi
|
||||
if grep -q "Unexpected end of JSON input" logs/playwright_extra_attempt_${attempt}.log \
|
||||
if { grep -q "Unexpected end of JSON input" logs/playwright_extra_attempt_${attempt}.log \
|
||||
|| grep -q "ERR_NO_BUFFER_SPACE" logs/playwright_extra_attempt_${attempt}.log; } \
|
||||
&& [ "$attempt" -lt "$max_attempts" ]; then
|
||||
echo "::warning::Playwright pipeTransport JSON crash on attempt ${attempt}; resetting Studio and retrying..."
|
||||
echo "::warning::Playwright flake on attempt ${attempt}; resetting Studio and retrying..."
|
||||
kill "${STUDIO_EXTRA_PID}" 2>/dev/null || true
|
||||
sleep 2
|
||||
unsloth studio reset-password
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue