Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug: [Flight] renderToReadableStream with Suspense never resolves in some circumstances #23113

Closed
jplhomer opened this issue Jan 14, 2022 · 2 comments
Labels
Status: Unconfirmed A potential issue that we haven't yet confirmed as a bug

Comments

@jplhomer
Copy link
Contributor

jplhomer commented Jan 14, 2022

React version: 0.0.0-experimental-0cc724c77-20211125 (and main)

Steps To Reproduce

  1. Build the current version of React in main
  2. open fixtures/flight-browser/index.html
  3. Take note that the model never resolves, and the HTML in the fixture is never updated:

Screen Shot 2022-01-14 at 3 10 58 PM

The current behavior

The model never resolves, and the data is never rendered to the DOM.

Other findings

  • If you console.log each chunk individually using response.getReader().read() ..., you'll see chunks written, but some are duplicates, and some are out of order. In the reader, done never gets called.
  • If you remove the Suspense read() from the Title component in the fixture, everything works correctly.
  • If you add add a console.log after let blob = await responseToDisplay.blob();, it never logs. This means that response.blob() is hanging.
  • If you replace the contents of display with renderResult(ReactServerDOMReader.createFromReadableStream(responseToDisplay.body)), everything works correctly.

We're seeing this same behavior in Hydrogen: Shopify/hydrogen#463 both when calling renderToReadableStream and passing that to Response in a Workers runtime, and when calling renderToReadableStream and consuming that stream in an SSR context. The chunks are written out of order and duplicated, and the response never resolves.

It's very odd that the automated tests in react-dom-server-webpack/.../ReactFlightDOMBrowser-test.js do not fail under these same conditions. I'm trying to pinpoint the conditions where this happens — e.g. is it when a ReadableStream gets sent through a Response.body? — but I can't nail it down yet.

The expected behavior

The flight model resolves when using renderToReadableStream with Suspense, and the data is rendered to the DOM.

@jplhomer jplhomer added the Status: Unconfirmed A potential issue that we haven't yet confirmed as a bug label Jan 14, 2022
@frandiox
Copy link
Contributor

I think I found this issue again when trying to buffer a ReadableStream using RSC in a Cloudflare Worker:

const readable = rscRenderToReadableStream(...);
let bufferedBody = '';
while (true) {
  const {done, value} = await reader.read();
  if (done) break;
  bufferedBody +=  decoder.decode(value);
}

return new Response(bufferedBody);

It reads a bunch of values in the while but eventually hangs without returning done = true

It works when using react-dom/server 's renderToReadableStream instead (SSR).

renderToPipeableStream in Node works well, though.

@jplhomer
Copy link
Contributor Author

Fixed in #23342

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Status: Unconfirmed A potential issue that we haven't yet confirmed as a bug
Projects
None yet
Development

No branches or pull requests

2 participants