Per-scope takeover for live nodes whose server value is still streaming (D8 follow-up to #3817)
I maintainer di solito rispondono entro 1 giorno
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 4/5
- Tempo stimato
- 3-5 giorni
- Idoneità per principianti
- 45/100
- Tipo di issue
- Funzionalità
- Chiarezza
- Abbastanza chiara
- Stato di attività
- Attiva
- Stack tecnologico
- javascript, typescript
- Ambito
- frontend
Direzione di ricerca
Read documentation/plans/stage8-connection-transport.md for D8 context, then study packages/web/test/hydration/live-shell-source-3764.spec.tsx to understand current behavior and required test cases. Examine the hydration implementation in the web package to see how live nodes take over and how loadingValue exemption works. Implement either server-recorded readers or value-replay with solid.LiveResumeFrom, ensuring existing tests pass and adding a test for a fast-boundary read with a pending slow boundary.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
Problem
D8 (Stage 8, documentation/plans/stage8-connection-transport.md) makes a live node take over, meaning it re-runs its compute and opens the live connection, when its own hydration scope releases. For a node in the shell, that's when the root pass ends. Its stated goal is "No live node waits on another boundary."
#3817 (fixing #3764) added an exception. A live node whose serialized value is still in flight when it arms takes over at hydration end, after the last streamed boundary on the page has hydrated. Nodes with a loadingValue are exempt. The fallback is needed because the boundary that reads the node claims its server DOM against that value. If the node takes over before the value arrives, it has nothing to replay, and the boundary can't claim: you get a duplicate or unclaimed DOM. That happens with the real live() transport too, since its local first yield on takeover is the value the node adopted, and there isn't one yet.
The cost is latency. A live source created in the shell and read only inside a streamed <Loading> now goes live only when the slowest boundary on the page hydrates. In practice that covers nearly every real source in that shape: a shell memo read only inside <Loading> misses the shell flush unless its first value is ready synchronously. In a server probe, three microtasks were already too late.
Motivating case: the room demo
examples/room's header creates presence in the shell and reads it inside <Loading>. The Archive panel lower on the page takes 4 s. With the fallback, the tab joins the room, and other tabs see it join, only after the Archive lands. The demo exists to show the opposite. Its comments now note the exception.
Why the client alone can't do better
The ideal gate is "take over once every boundary that reads this node has hydrated." The client can't know that set. When the root pass ends, a pending boundary is an owner with no children, because its children are created when its fragment arrives. So until each boundary hydrates, nothing on the client can tell whether it will read the node. Walking the node's current observers only sees readers that already exist.
Candidate directions
- Server-recorded readers.
- During SSR, record for each serialized shell node the ids of the streamed boundaries that read it, and ship that list with the payload, either beside the value or in the readers' fragment data.
- On the client, the node's gate counts down as those boundaries release, falling back to hydration end, and nodes read by no boundary keep root scope.
- This preserves D8 exactly, at the cost of a read hook on the server memo path, payload bytes, and an estimated 120–250 B minified on the client.
- Take over once the node's own value has arrived, replaying it.
- Keep the per-scope gate, but for an in-flight node also wait until its serialized value lands. Then stamp the takeover with that value (
solid.LiveResumeFrom), so the transport yields it locally before connecting and the reading boundary still claims against the server value. - A prototype made during #3817's review found:
- Flipping the gate on the settle alone loses a race: the takeover supersedes the adoption before the value commits. Resuming from the landed value fixes that deterministically.
- It fixes #3764's case A and keeps the fast-boundary and
loadingValuecases prompt. - It relies on the source honoring the replay protocol, so hand-rolled branded iterables still fail.
- Residual failure: when a value lands before a slower boundary that reads it, and the server's data genuinely changes in that gap, the boundary claims against changed data.
- As written it added about +183 B minified to hydrating bundles (three scenarios over cap). A tighter version is likely near 100 B.
- Keep the per-scope gate, but for an in-flight node also wait until its serialized value lands. Then stamp the takeover with that value (
Either direction should keep #3817's tests (both case-A timings in packages/web/test/hydration/live-shell-source-3764.spec.tsx) and the loadingValue test passing. It should also add a test for a node read by a fast boundary while an unrelated slow boundary is pending, which should connect before the slow boundary lands.
- Lingua principale
- TypeScript
- Stelle
- 36.1k
- Fork
- 1.1k
- Merge medio
- 11h 45m
- PR unite (30g)
- 329
Preparare l'ambiente
- Nessun Dockerfile né file Docker Compose
- Ha un modello di pull request
- Leggi la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di solidjs/solid
-
CHEATSHEET.md and RFC 02 still recommend module-scope state for app-wide state (follow-up to #3390)Aperta
Difficoltà 1/5 1-3 ore Idoneità per principianti 86/100
I maintainer di solito rispondono entro 1 giorno
-
`lazy()`: remounting an already-loaded component renders empty (or the Suspense fallback) since 1.9.14Forse già presa @itisrmk l’ha presa 2 giorni fa. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 62/100
I maintainer di solito rispondono entro 1 giorno
-
[2.0 / next] Recovering before a held error commits throws the successful valueForse già presa Una pull request collegata a questa issue è aperta o già unita. Aperta
Difficoltà 4/5 1-2 giorni Idoneità per principianti 48/100
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 4/5 3-5 giorni Idoneità per principianti 48/100
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 4/5 3-5 giorni Idoneità per principianti 42/100
I maintainer di solito rispondono entro 1 giorno
Tutte le issue di solidjs/solid
Issue simili
-
[测试] 等待仓库加载后再记录多仓库排序基线Forse già presa @myot233 l’ha presa oggi. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 84/100
I maintainer di solito rispondono entro 1 giorno
-
area:arcade p3-medium ready-for-agent testing type:docs
Difficoltà 2/5 1-3 ore Idoneità per principianti 76/100
fderuiter/deruiter.dev#2369 ·
I maintainer di solito rispondono entro 1 giorno
-
area:devenv origin:agent type:bug
Difficoltà 2/5 1-3 ore Idoneità per principianti 84/100
overengineeringstudio/effect-utils#1949 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 76/100
ccch1mneyyy/dsh-TUI#1631 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
MiniMax-AI/minimax-code#507 ·
I maintainer di solito rispondono entro 1 giorno