Repository navigation
Correct the live view reason rows and watchdog guidance - #704
Conversation
|
Preview deployment for your docs. Learn more about Mintlify Previews.
💡 Tip: Enable Automations to automatically generate PRs for you. |
The snippet remounted 15s after mount. The client's connect bounds run in sequence and sum to 23s, so an embedder following the example tore the frame down before the client could report which stage stalled — including media, the stage most likely to have stalled. Also correct the note about KERNEL_CONNECTION_TIMEOUT never firing once negotiation begins. The media bound stays armed past `checking` until ICE reaches `connected`, so a connect that stalls in between does report one; what never emits it is a viewer whose frames stop after it connected.
Sayan-
left a comment
There was a problem hiding this comment.
overal looks good. needs a deslop to conform to docs language guidance
…ance The example remounts at 35s, above the client's connect bounds, which run in sequence (transport, signaling, media) and now sum to 28s after kernel-images#472 settled the media bound at 10s. Below the budget the example reproduces the bug this page was fixing: the embedder tears the frame down before the client can name the stage that stalled. The prose around it says what the timer has to clear and why, since the timer also covers loading the frame and waking a sleeping browser. The timeout warning names `completed` alongside `connected`, which is the other way the media bound clears. The `media` row now reads "connected or completed ... covers a peer that stalls after checking", folded in from #698, which this supersedes.
…udget The media bound stays at its interim ceiling. The stretch through ICE `connected` is unmeasured in every region, so shortening the default is not something the probe data supports yet; a region that has the timings lowers it through the live view proxy's override instead. With the defaults unchanged, the three bounds sum to 48s rather than 28s, so the example timer moves to 50s to stay above the budget it has to outlast.
masnwilliams
left a comment
There was a problem hiding this comment.
lgtm. the media row and the timeout note now match the client: the bound stays armed until ICE reaches connected or completed, and the 48s total checks out against the 15/3/30 defaults. a few small notes inline, none blocking.
non-blocking follow-up, separate from this PR: the transport and peer rows still don't match how the client picks a reason. a socket close at any point before the connect succeeds reports transport, not only before signaling. ICE failed/closed or the data channel closing before connect falls through to peer. that makes the line 166 advice wrong for ICE failures, since remounting can fix a network-path failure. worth a separate pass.
| ### Detecting a viewer that never starts | ||
|
|
||
| Gate on `KERNEL_PLAYING`. It fires only once frames actually arrive, so it is the signal that distinguishes a working viewer from one that is still connecting or has silently failed. The terminal events below tell you when the client has stopped trying. Start a timer when you mount the iframe and remount if `KERNEL_PLAYING` has not arrived: | ||
| Gate on `KERNEL_PLAYING`. It fires only once frames actually arrive, so it is the signal that distinguishes a working viewer from one that is still connecting or has silently failed. The terminal events below tell you when the client has stopped trying. Start a timer when you mount the iframe and remount if `KERNEL_PLAYING` has not arrived. The timer has to outlast the client's connect bounds, which run in sequence — transport, then signaling, then media — and sum to 48s by default. If you wait less than that, you'll tear the frame down before it can report a stage that stalled late. The timer also covers loading the frame, including waking a browser that has gone to sleep, so leave room above the budget when you set it: |
There was a problem hiding this comment.
the wake doesn't add time on top of the budget. the proxy wakes the browser before the socket opens, so that time is already inside the 15s transport bound. only loading the page itself is extra. maybe:
| Gate on `KERNEL_PLAYING`. It fires only once frames actually arrive, so it is the signal that distinguishes a working viewer from one that is still connecting or has silently failed. The terminal events below tell you when the client has stopped trying. Start a timer when you mount the iframe and remount if `KERNEL_PLAYING` has not arrived. The timer has to outlast the client's connect bounds, which run in sequence — transport, then signaling, then media — and sum to 48s by default. If you wait less than that, you'll tear the frame down before it can report a stage that stalled late. The timer also covers loading the frame, including waking a browser that has gone to sleep, so leave room above the budget when you set it: | |
| Gate on `KERNEL_PLAYING`. It fires only once frames actually arrive, so it is the signal that distinguishes a working viewer from one that is still connecting or has silently failed. The terminal events below tell you when the client has stopped trying. Start a timer when you mount the iframe and remount if `KERNEL_PLAYING` has not arrived. The timer has to outlast the client's connect bounds, which run in sequence — transport, then signaling, then media — and sum to 48s by default. If you wait less than that, you'll tear the frame down before it can report a stage that stalled late. The timer also covers loading the frame itself, so leave room above the budget when you set it: |
| iframe.src = src; | ||
| arm(); | ||
| }, 15000); | ||
| }, 50000); |
There was a problem hiding this comment.
nit: 50s leaves 2s over a 48s budget, which is thin for "leave room above the budget", and once the bounds can be tuned per region the budget can grow past 48s. 60s seems safer and costs little, because FAILED/TIMEOUT already show the fallback right away and this timer only catches silent stalls.
| }, 50000); | |
| }, 60000); |
| ``` | ||
|
|
||
| Do not gate on `KERNEL_CONNECTION_TIMEOUT` alone. The watchdog behind it is cleared once negotiation begins, so a connection that stalls after that point never emits it. Log it alongside `KERNEL_PLAYING` to capture the connection state at the moment things stalled. | ||
| Do not gate on `KERNEL_CONNECTION_TIMEOUT` alone. It only covers a connect that is still negotiating: the media bound clears once ICE reaches `connected` or `completed`, and a viewer whose frames stop after it connected never emits one. Log it alongside `KERNEL_PLAYING` to capture the connection state at the moment things stalled. |
There was a problem hiding this comment.
nit: the docs style guide asks for contractions.
| Do not gate on `KERNEL_CONNECTION_TIMEOUT` alone. It only covers a connect that is still negotiating: the media bound clears once ICE reaches `connected` or `completed`, and a viewer whose frames stop after it connected never emits one. Log it alongside `KERNEL_PLAYING` to capture the connection state at the moment things stalled. | |
| Don't gate on `KERNEL_CONNECTION_TIMEOUT` alone. It only covers a connect that is still negotiating: the media bound clears once ICE reaches `connected` or `completed`, and a viewer whose frames stop after it connected never emits one. Log it alongside `KERNEL_PLAYING` to capture the connection state at the moment things stalled. |
The prose said the timer covers waking a browser. It doesn't: the proxy wakes the browser before the socket opens, so that time is already inside the transport bound, and only loading the page itself is extra. The example timer moves to 60s. 50s left 2s over the 48s budget, which is thin for "leave room above the budget", and a region that raises its bounds moves the budget past 48s anyway. The earlier terminal events still show the fallback as soon as they arrive, so this timer only catches a silent stall. Also contracts "Do not" to "Don't", which the docs style guide asks for.
0df7e22 to
cf3da30
Compare
A socket close at any point before the connect succeeds reports `transport`, not only one before signaling, and `peer` also covers ICE reaching `failed` or `closed` and the data channel closing before the connect. The retry advice follows: remounting repeats a construction or offer throw, but it can fix an ICE failure, so that case is worth one retry.
| ### Detecting a viewer that never starts | ||
|
|
||
| Gate on `KERNEL_PLAYING`. It fires only once frames actually arrive, so it is the signal that distinguishes a working viewer from one that is still connecting or has silently failed. The terminal events below tell you when the client has stopped trying. Start a timer when you mount the iframe and remount if `KERNEL_PLAYING` has not arrived: | ||
| Gate on `KERNEL_PLAYING`. It fires only once frames actually arrive, so it is the signal that distinguishes a working viewer from one that is still connecting or has silently failed. The terminal events below tell you when the client has stopped trying. Start a timer when you mount the iframe and remount if `KERNEL_PLAYING` has not arrived. The timer has to outlast the client's connect bounds, which run in sequence — transport, then signaling, then media — and sum to 48s by default. If you wait less than that, you'll tear the frame down before it can report a stage that stalled late. The timer also covers loading the frame itself, so leave room above the budget when you set it: |
There was a problem hiding this comment.
I'm not sure we should be encoding timeout values in our docs, esp since we may tune these dynamically, etc. I don't have a counter proposal, however, at this point.
Sayan-
left a comment
There was a problem hiding this comment.
Thanks for iterating! No other blocks from me
## Summary The per-stage connect bounds the live view client arms while connecting are now served with the page instead of compiled into the bundle, so a region can retune one without a browser image release. This follows review feedback on the earlier revision of this branch, which shortened the media bound in the client. The bounds are read at load from window.KERNEL_LIVE_VIEW_CONNECT_TIMEOUTS_MS, which the live-view proxy injects ahead of the first script in the page from its own environment (kernel/kernel#4889, kernel/infra#1693). A stage the proxy does not name, or names with a value that is not a positive number of milliseconds, keeps the default the image ships, so the client behaves the same on a proxy that injects nothing. The defaults stay transport 15s, signaling 3s and media 30s, a worst case of 48s across the three, and a test pins them so a silent change fails CI. ## Why the media default stays at 30s The bound covers the connect through ICE `connected`, and that stretch is unmeasured in every region: 44 of the 130 probe runs stopped at `checking`, all 30 ap-southeast runs among them. The measured paths land in 1-16ms direct and \~90ms relay-only, which is what made a shorter default tempting, but an expired bound is terminal and the client does not retry, so the default stays at the ceiling the data supports rather than the shortest value that fits the measured regions. A region with the timings lowers it through the override. Transport stays at 15s: the live-view proxy can spend \~12s waking a browser before the socket opens, so shortening it would report a slow wake as dead. ## Testing `bun test tests` in images/chromium-headful/client, 235 pass, 0 fail, including cases for a partial override, values that are not positive milliseconds, an unknown stage, and the shipped defaults being the documented 15 / 3 / 30. `tsc --noEmit` clean. ## Related browsers/live-view.mdx moves with this in kernel/docs#704: the example watchdog goes from 15s to 50s, above the 48s budget, and the sentence claiming KERNEL_CONNECTION_TIMEOUT stops firing once negotiation begins, which describes the pre-kernel-images#417 client, is corrected.
Three corrections to the live view embedding guidance, plus a pass over the prose that changed.
The
mediareason row. It said the bound expires if ICE never reachedchecking. Since kernel-images#417 the client keeps the media bound armed throughconnected, so it expires only if ICE never arrives atconnectedorcompleted—completedis the other way a healthy connect can land when gathering is already done. An embedder branching onreasonwould otherwise expectmediato fire earlier than it does. This row is the one kernel/docs#698 carried, which this PR supersedes.The example watchdog. It remounted 15s after mount. The client's connect bounds run in sequence — transport, then signaling, then media — and sum to 48s, so an embedder following the snippet tore the frame down before the client could report which stage stalled. The example now uses 60s, and the prose says why the timer needs room above the budget: it also covers loading the frame itself.
The
transportandpeerrows. A socket close at any point before the connect succeeds reportstransport, not only one before signaling, andpeeralso covers ICE reachingfailedorclosedand the data channel closing before the connect. The retry advice under the example follows: remounting repeats a construction or offer throw, but it can fix an ICE failure, so that case is worth one retry.The note claiming
KERNEL_CONNECTION_TIMEOUTstops firing once negotiation begins is corrected the same way: the media bound stays armed pastcheckinguntil ICE reachesconnectedorcompleted, so a connect stalling in between does report one. What never emits it is a viewer whose frames stop after it connected.Paired with kernel-images#472, which serves the bounds with the page from the live view proxy's environment, so a region can retune them without a browser image release. The defaults stay at transport 15s, signaling 3s and media 30s. Merge order doesn't matter for the docs themselves, but the two describe the same client.
Docs only, prose and one snippet constant. I didn't run
mint broken-linkson this revision becausemintisn't installed in this environment; the change touches no links and the check passed on the previous revision.Note
Low Risk
Documentation-only changes to live view embedding guidance; no runtime or API behavior changes in this repo.
Overview
Updates live view iframe embedding docs so
reasonhandling and watchdog timing match current client connect behavior.The
mediatimeout reason now states ICE must reachconnectedorcompletedwithin the bound (not merelychecking), including peers that stall afterchecking.KERNEL_CONNECTION_TIMEOUTguidance is updated the same way: the media bound stays active until those states, and viewers that lose frames after a successful connect will not emit it.The example remount watchdog increases from 15s to 50s, with new prose that sequential connect stages default to 48s total and embedders should allow extra time for iframe load and waking a sleeping browser.
Reviewed by Cursor Bugbot for commit 044c381. Bugbot is set up for automated code reviews on this repo. Configure here.
Note
Low Risk
Documentation-only updates to embedding guidance; no runtime or API behavior changes.
Overview
Updates live view embedding docs so they match current client connect behavior (post kernel-images#417).
The
mediatimeoutreasonis corrected: the bound applies until ICE reachesconnectedorcompleted, not merelychecking, so embedders branching onreasonwon't expectmediatoo early.The “viewer never starts” section adds that default stage timeouts sum to 48s (transport → signaling → media) and that remount timers must exceed that budget plus iframe load time. The sample watchdog timeout changes from 15s to 60s.
Guidance on
KERNEL_CONNECTION_TIMEOUTis rewritten: the media bound clears atconnected/completed(not when negotiation starts), so mid-connect stalls can still emit the event; viewers that fail after frames were playing will not.Reviewed by Cursor Bugbot for commit cf3da30. Bugbot is set up for automated code reviews on this repo. Configure here.
Note
Low Risk
Documentation-only updates to live view embedding guidance; no runtime or API changes in this repo.
Overview
Aligns live view iframe embedding docs in
browsers/live-view.mdxwith current connect-stage behavior so embedders branch onreasonand watchdog timing correctly.The
reasontable is updated:transportcovers socket closure anytime before connect succeeds;mediafires when ICE never reachesconnectedorcompleted(not merelychecking);peeralso covers ICEfailed/closedand early data-channel closure.The “never starts” section adds that default stage bounds run transport → signaling → media and sum to 48s, so remount timers must exceed that plus iframe load. The sample watchdog changes from 15s to 60s.
KERNEL_CONNECTION_TIMEOUTprose now matches the media bound (clears atconnected/completed; no timeout after a successful connect). Remount guidance splitspeerby cause—environment vs network—and limits blind retries accordingly.Reviewed by Cursor Bugbot for commit 46f1d17. Bugbot is set up for automated code reviews on this repo. Configure here.