Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: react/react
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: c0cd4d5d
Choose a base ref
...
head repository: react/react
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: f0dfee38
Choose a head ref
  • 4 commits
  • 9 files changed
  • 2 contributors

Commits on May 27, 2026

  1. Configuration menu
    Copy the full SHA
    75ae73e View commit details
    Browse the repository at this point in the history
  2. [Flight] Fix stranded row content under Node stream backpressure (#36516

    )
    
    The Flight Server emits Text and TypedArray rows as two chunks: a header
    that gives the row's id, type, and content length, followed by the
    content itself. These two chunks were pushed into
    `completedRegularChunks` (and `completedDebugChunks` in DEV) as separate
    items, so when the destination signaled backpressure between them, the
    flush would write the header and then break out before reaching the
    content. The content chunk was left stranded at the head of the queue.
    Async work running while the destination was paused appended new rows to
    `completedImportChunks` / `completedHintChunks`, and the next drain
    flushed those queues first — splicing the newly-arrived bytes into the
    position the Flight Client expects to read as the original row's
    content. From there the Flight Client read rows from the wrong byte
    offsets and the model failed to deserialize.
    
    This only surfaced on the Node stream path.
    `createFakeWritableFromReadableStreamController`, used by
    `renderToReadableStream`, always returns `true` from `write()`, so the
    flush loop never saw backpressure.
    
    The fix pushes a `NEXT_TWO_CHUNKS_ARE_ATOMIC` sentinel ahead of each
    `headerChunk` / `contentChunk` pair in `completedRegularChunks` and
    `completedDebugChunks`. The flush loops detect the sentinel and write
    the two chunks that follow it together before re-checking backpressure,
    so backpressure can still break between rows but never within one.
    
    ### Alternatives considered
    
    - **Pushing the pair as a `[headerChunk, contentChunk]` tuple.** Simpler
    but allocates an array per row. The required `isArray` branch in the
    flush hot path is likely comparable with the symbol check. This also
    violates the opaque `Chunk` type boundary.
    - **Concatenating header and content into one chunk.** Bad for memory —
    typed-array content can be large.
    - **Storing atomic groups in a separate queue.** Conceptually wrong and
    risks breaking reference-ordering assumptions between rows.
    - **Ignoring backpressure until the regulars queue is empty.** Defeats
    the point of backpressure.
    - **Wrapping the tuple behind a host-config API** (`writeAdjacentChunks`
    / `isAdjacentChunks` / `chunksToAdjacentChunks` /
    `getAdjacentChunksLength`). Keeps the implementation opaque but adds
    four exports per host config. Also has the tuple overhead.
    - **Begin/end sentinels for variable-length atomic groups.** Not needed
    — only Text and TypedArray rows use this pattern, and both are pairs.
    unstubbable authored May 27, 2026
    Configuration menu
    Copy the full SHA
    c014813 View commit details
    Browse the repository at this point in the history

Commits on May 28, 2026

  1. Configuration menu
    Copy the full SHA
    6b5ea12 View commit details
    Browse the repository at this point in the history

Commits on May 29, 2026

  1. Configuration menu
    Copy the full SHA
    f0dfee3 View commit details
    Browse the repository at this point in the history
Loading