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

Fallback to default injectToStream when react-streaming stream is closed #1718

Closed
wants to merge 7 commits into from

Conversation

magne4000
Copy link
Member

@magne4000 magne4000 commented Jun 27, 2024

Fixes vikejs/bati#283

PS: I'm not sure why imports are reordered, it's disabled in my IDE (perhaps biome does that?)

@magne4000 magne4000 requested a review from brillout June 27, 2024 13:38
@magne4000 magne4000 marked this pull request as draft June 27, 2024 13:45
@brillout
Copy link
Member

This would await for the stream to completely end though, see docs about streamEnd at https://github.com/brillout/react-streaming.

Thus, this will probably break progressive rendering. You can test that at /examples/react-streaming. (We should probably add some progressive rendering tests at some point.)

PS: I'm not sure why imports are reordered, it's disabled in my IDE (perhaps biome does that?)

There isn't any automatic formatting, so I'm inclined to think it's something on your side.

@magne4000
Copy link
Member Author

Yup I noticed that's not the fix we need, we would need a way to check if the underlying streamOriginal is closed, but I'm not sure we have that available

@brillout
Copy link
Member

brillout commented Jun 27, 2024 via email

@magne4000
Copy link
Member Author

Looking at the log, I would say Vike itself or Vite:

Error: [[email protected]][Wrong Usage] Cannot inject following chunk after stream has ended: `<script id="vike_pageContext" type="application/json">{"$$typeof":"!undefined","abortReason":"!undefined","_urlRewrite":null,"_urlRedirect":"!undefined","abortStatusCode":"!undefined","_abortCall":"!undefined","_pageContextInitIsPassedToClient":"!undefined","_pageId":"/pages/_error","routeParams":{},"data":"!undefined","pageProps":{"is404":false},"is404":false,"_isServerSideError":"!undefined"}</script><script type="module" async>
import RefreshRuntime from "/@react-refresh"
RefreshRuntime.injectIntoGlobalHook(window)
window.$RefreshReg$ = () => {}
window.$RefreshSig$ = () => (type) => type
window.__vite_plugin_react_preamble_installed__ = true
import "/@vite/client";
import "/@fs/tmp/bati-app/node_modules/.pnpm/[email protected][email protected][email protected][email protected][email protected][email protected]_@[email protected]_/node_modules/vike/dist/esm/client/client-routing-runtime/entry.js";
</script>`
    at injectToStream (/tmp/bati-app/node_modules/.pnpm/[email protected][email protected][email protected][email protected]/node_modules/react-streaming/dist/cjs/server/renderToStream/createBuffer.js:12:33)
    at injectHtmlFragment (file:///tmp/bati-app/node_modules/.pnpm/[email protected][email protected][email protected][email protected][email protected][email protected]_@[email protected]_/node_modules/vike/dist/esm/node/runtime/html/injectAssets/injectHtmlTags.js:48:9)
    at file:///tmp/bati-app/node_modules/.pnpm/[email protected][email protected][email protected][email protected][email protected][email protected]_@[email protected]_/node_modules/vike/dist/esm/node/runtime/html/injectAssets/injectHtmlTags.js:16:26
    at Array.forEach (<anonymous>)
    at injectHtmlTags (file:///tmp/bati-app/node_modules/.pnpm/[email protected][email protected][email protected][email protected][email protected][email protected]_@[email protected]_/node_modules/vike/dist/esm/node/runtime/html/injectAssets/injectHtmlTags.js:10:15)
    at injectToHtmlBegin (file:///tmp/bati-app/node_modules/.pnpm/[email protected][email protected][email protected][email protected][email protected][email protected]_@[email protected]_/node_modules/vike/dist/esm/node/runtime/html/injectAssets.js:41:17)
    at injectAtStreamBegin (file:///tmp/bati-app/node_modules/.pnpm/[email protected][email protected][email protected][email protected][email protected][email protected]_@[email protected]_/node_modules/vike/dist/esm/node/runtime/html/injectAssets.js:25:21)
    at injectStringAtBegin (file:///tmp/bati-app/node_modules/.pnpm/[email protected][email protected][email protected][email protected][email protected][email protected]_@[email protected]_/node_modules/vike/dist/esm/node/runtime/html/renderHtml.js:68:24)

@brillout
Copy link
Member

This chunk is indeed authored by Vike (not Vite).

Both Vike (DEBUG=vike:stream) and react-streaming (brillout/react-streaming@c98b1a5) have debug logs to see what happens when. It's usually an effective way to get to the bottom of these kind of issues. But let me know if you want me to have a look at it.

@magne4000
Copy link
Member Author

But let me know if you want me to have a look at it.

Could be great yes.

I'm not sure if the stream created by react-streaming in createReadableWrapper should be kept open until further notice (but what does it even mean in this case? and how does this then apply to other frameworks supporting streaming?).

Intuitively, I would have injectToStream be a wrapper around any underlying Stream, but it would ignore close (non-error) events from underlying stream (i.e. React stream), and only listen for close events coming from "above" (i.e. Vike or Vite, I'm confused here).

@brillout
Copy link
Member

How can I reproduce the issue?

@magne4000
Copy link
Member Author

magne4000 commented Jun 27, 2024

For now I was testing with those instructions vikejs/bati#283 (comment) (and fiddling directly in node_modules)

@magne4000
Copy link
Member Author

I tried with stream: 'node' and:

// vike-handler.ts
import { Writable } from 'node:stream';
...
const { readable, writable } = new TransformStream();

response?.pipe(Writable.fromWeb(writable));

return new Response(readable, {
  status: response?.statusCode,
  headers: response?.headers,
});
...

and no error, so at least it's contained to Web streams mode.

@magne4000
Copy link
Member Author

magne4000 commented Jun 27, 2024

For now I was testing with those instructions batijs/bati#283 (comment) (and fiddling directly in node_modules)

I just disabled stream mode by default in Bati, so you perhaps need to manually add stream: 'web' back to +config.ts

@magne4000
Copy link
Member Author

Weirdly enough, if I try to copy the reproduction repo in vike/examples I have no issue (but streaming seems disabled) 😕

@brillout
Copy link
Member

👍 I'll have a look.

@magne4000
Copy link
Member Author

magne4000 commented Jun 27, 2024

Weirdly enough, if I try to copy the reproduction repo in vike/examples I have no issue (but streaming seems disabled) 😕

🤕 I was testing on this branch with my "fix"...

Anyway, I removed the fix, and pushed the repo in vike/examples/bati-app for testing purpose.

@brillout
Copy link
Member

I can reproduce.

@brillout brillout force-pushed the magne4000/fix-inject-stream branch from ccdf218 to 16d374b Compare June 27, 2024 21:03
@brillout
Copy link
Member

Actually, I cannot reproduce anymore.

Neither on this PR nor on https://github.com/brillout/vike-stream-bug-2024-06. Can you systematically reproduce or is it random?

@brillout
Copy link
Member

I just pushed this tentative fix on brillout/dev. I'm shooting in the dark as I cannot reproduce; let me know if it fixes the issue (you can test the fix by rebasing this PR onto brillout/dev).

@magne4000
Copy link
Member Author

magne4000 commented Jun 27, 2024

Actually, I cannot reproduce anymore.

Neither on this PR nor on https://github.com/brillout/vike-stream-bug-2024-06. Can you systematically reproduce or is it random?

Yup still reproduce, even managed get the issue on a second machine

I just pushed this tentative fix on brillout/dev. I'm shooting in the dark as I cannot reproduce; let me know if it fixes the issue (you can test the fix by rebasing this PR onto brillout/dev).

I'll try that

@magne4000 magne4000 force-pushed the magne4000/fix-inject-stream branch from 16d374b to c40109e Compare June 27, 2024 22:50
@magne4000 magne4000 changed the base branch from main to brillout/dev June 27, 2024 22:50
@magne4000
Copy link
Member Author

magne4000 commented Jun 27, 2024

After a quick pnpm dedupe, it at first seems to have fixed the issue (and at least server-side no more error). But it generates an interesting side effect on the client:
image

The added code after the stream closes makes React confused when trying to rehydrate on the client.

@brillout
Copy link
Member

That's actually something I was expecting, let me try to reproduce on my machine.

@brillout
Copy link
Member

I can reproduce. Let me dig & fix.

@brillout
Copy link
Member

I believe #1722 fixes it.

I ain't sure because I couldn't reproduce the error without the fix. But we can be confident this works if: you can reproduce the error by reverting the fix, then re-apply the fix and then not be able to reproduce the error.

@magne4000
Copy link
Member Author

I do not have issues anymore on #1722 but how can I make sure that streaming is actually working?

@brillout
Copy link
Member

brillout commented Jul 1, 2024

With working do you mean that it doesn't throw the error anymore or that progressive rendering works?

@magne4000
Copy link
Member Author

With working do you mean that it doesn't throw the error anymore or that progressive rendering works?

The I have no error, but I'm not sure I have progressive rendering, what's the best way to test it?

@brillout
Copy link
Member

brillout commented Jul 1, 2024

There is a progressive rendering example at /examples/react-streaming/.

@brillout
Copy link
Member

brillout commented Jul 1, 2024

FYI DEBUG=vike:stream,react-streaming:buffer can be quite helpful.

@magne4000
Copy link
Member Author

magne4000 commented Jul 1, 2024

@brillout progressive rendering works both with Node Stream and Web Stream with latest vike-react and react-streaming 🚀

@brillout
Copy link
Member

brillout commented Jul 1, 2024

Even with the universal adapter? 👀

@magne4000
Copy link
Member Author

Yes, that is what I was testing with my latest push 0cc3cbc

@brillout
Copy link
Member

brillout commented Jul 1, 2024

Nice 🚀

@magne4000
Copy link
Member Author

magne4000 commented Jul 1, 2024

@brillout I guess that a proper fix requires only to bump vike-react and react-streaming. Do you want me to create another PR for that?

@brillout
Copy link
Member

brillout commented Jul 1, 2024

Hm, that's surprising as I think #1722 is required to avoid the race condition. There wasn't any fix regarding the race condition error in react-streaming nor vike-react.

I suggest we merge 1722 in the hope it fixes the error, then let's have a look at it again if a user complains.

I'm working on a react-streaming feature right now, then I'll merge 1722.

@brillout
Copy link
Member

brillout commented Jul 3, 2024

Fixed at #1722 and released in 0.4.178.

@brillout brillout closed this Jul 3, 2024
@magne4000 magne4000 deleted the magne4000/fix-inject-stream branch July 3, 2024 15:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Question about react streaming
2 participants