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

.pipeTo(Writable.toWeb(process.stdout)) returns a never-settling Promise #56139

Open
mikaelkaron opened this issue Dec 5, 2024 · 7 comments
Open

Comments

@mikaelkaron
Copy link

mikaelkaron commented Dec 5, 2024

Version

  • v22.9.0
  • v22.12.0
  • v23.3.0

Platform

Linux a54ff73afbfe 5.15.153.1-microsoft-standard-WSL2 #1 SMP Fri Mar 29 23:14:13 UTC 2024 x86_64 GNU/Linux
Linux SURFACE9PRO 5.15.153.1-microsoft-standard-WSL2 #1 SMP Fri Mar 29 23:14:13 UTC 2024 x86_64 x86_64 x86_64 GNU/Linux

Subsystem

node:stream

What steps will reproduce the bug?

create file test.mjs

import { Readable, Writable } from 'node:stream'

await Readable.toWeb(process.stdin).pipeTo(Writable.toWeb(process.stdout))

run

echo test | node test.mjs 
test
Warning: Detected unsettled top-level await at file:///workspace/test.mjs:2
await Readable.toWeb(process.stdin).pipeTo(Writable.toWeb(process.stdout))
^

How often does it reproduce? Is there a required condition?

always

What is the expected behavior? Why is that the expected behavior?

no warning, await to work as expected

What do you see instead?

warning about unsettled top-level await is shown

Additional information

No response

@mikaelkaron
Copy link
Author

Some (small followups):

Simplified to get rid of Readable.toWeb

import { Writable } from 'node:stream'
import { ReadableStream } from 'node:stream/web'

await ReadableStream.from(["test"]).pipeTo(Writable.toWeb(process.stdout))
node test.mjs 
testWarning: Detected unsettled top-level await at file:///workspace/test.mjs:4
await ReadableStream.from(["test"]).pipeTo(Writable.toWeb(process.stdout))
^

Without Writable.toWeb there's no error:

import { ReadableStream } from 'node:stream/web'

await ReadableStream.from(["test"]).pipeTo(new WritableStream())

And just to make sure let's implement a naive implementation of a WritableStream

import { ReadableStream } from 'node:stream/web'
import { setTimeout } from 'node:timers/promises'

const streamWritable = process.stdout

await ReadableStream.from(["test"]).pipeTo(new WritableStream({
  write(chunk) {
    if (streamWritable.writableNeedDrain || !streamWritable.write(chunk)) {
      return new Promise(resolve => streamWritable.once('drain', resolve))
    }
  },
  close() {
    return setTimeout(1000)
  }
}))

@aduh95
Copy link
Contributor

aduh95 commented Dec 5, 2024

The problem is not that there's a warning, it's that the promise never resolves:

$ node -e '
const {Writable} = require("node:stream");
const {ReadableStream} = require("node:stream/web");
ReadableStream.from(["test\n"]).pipeTo(Writable.toWeb(process.stdout)).then(() => console.log("Done"), console.error)'
test
$ echo $?
0

As you can see, the console.log("Done") is never reached. The warning is a mere consequence of awaiting a never-settling promise on the top-level scope.

@aduh95 aduh95 changed the title awaiting .pipeTo(Writable.toWeb(process.stdout)) results in warning .pipeTo(Writable.toWeb(process.stdout)) returns a never-settling Promise Dec 5, 2024
@mikaelkaron
Copy link
Author

mikaelkaron commented Dec 7, 2024

The problem is not that there's a warning, it's that the promise never resolves:

Indeed. I had a few extra minutes to do some initial testing. I looks like when the code gets here closed is undefined which returns a promise here.

I'm guessing closed is supposed to be handled in cleanup but when I debug I never get there which leads me to suspect that eos is not running the supplied callback for some reason.

So that was me not setting up my debugging env propperly, the callback is executed, so I'll have to dig some more.

@mikaelkaron
Copy link
Author

mikaelkaron commented Dec 8, 2024

I decided to go in a slightly different direction and started testing with different node version, and it look like this works in v21.7.3, but is broken in v22.0.0. Also tested in in v23.3.0 where it's also broken.

@aduh95
Copy link
Contributor

aduh95 commented Dec 9, 2024

It could be related to a V8 update, or another semver-major commit of v22.x but I don't see any related

@jakecastelli
Copy link
Member

The reason you won't see the warning in v21.7.3 but see in v22.0.0 is because since v22.0.0 it starts to detect unsettled top-level await - see this commit - more detail please take a look at this PR #51999.

I have tested v21.7.3 locally and the issue described by @aduh95 (here) still exists.

@mikaelkaron
Copy link
Author

Oh well, I guess it's nice to have found something new rather than a regression 🤷

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants