bun
bun copied to clipboard
`Bun.stdin.stream()` not working beyond top-level `await`
What version of Bun is running?
0.3.0 --canary
What platform is your computer?
Linux 4.4.0-17763-Microsoft x86_64 x86_64
What steps can reproduce the bug?
$ cat bad.js
var line, reader = Bun.stdin.stream().getReader();
(async function() {
while (!(line = await reader.read()).done) {
console.log(line);
}
console.log('DONE', line);
})();
What is the expected behavior?
$ cat good.js
var line, reader = Bun.stdin.stream().getReader();
while (!(line = await reader.read()).done) {
console.log(line);
}
console.log('DONE', line);
(Typed abc<Enter><Ctrl+D>)
$ bun good.js
abc
{
value: Uint8Array(4) [ 97, 98, 99, 10 ],
done: false
}
{
value: Uint8Array(0) [ ],
done: false
}
DONE {
value: undefined,
done: true
}
What do you see instead?
$ bun bad.js
abc
$
Additional information
Just thought I'd file a separate issue from #1604 as this isn't related to Node.js − refer to https://github.com/oven-sh/bun/issues/1604#issuecomment-1345647940 onwards for more examples of failure.
I think this bug is that we aren't ref/unref'ing stdin correctly
I think you are right:
$ cat hack.js
var timerId;
function resume() {
timerId = setInterval(function() {}, 1e9);
}
function pause() {
clearInterval(timerId);
}
(async function() {
var line, reader = Bun.stdin.stream().getReader();
resume();
while (!(line = await reader.read()).done) {
console.log(line);
}
pause();
console.log('DONE', line);
})();
(Typed abc<Enter><Ctrl+D>)
$ bun hack.js
abc
{
value: Uint8Array(4) [ 97, 98, 99, 10 ],
done: false
}
{
value: Uint8Array(0) [ ],
done: false
}
DONE {
value: undefined,
done: true
}
$
So I guess the question is, where is the code responsible for Bun.stdin being ref() which somehow only works when top-level await is being performed?
$ cat test.js
// same results with:
// var reader = Bun.file(process.stdin.fd).stream().getReader();
var reader = Bun.stdin.stream().getReader();
(async function() {
do {
var { done, value } = await reader.read();
console.log(value);
} while (!done);
console.log("ENDED");
})();
Captures the immediately available abc, then abruptly exits (read: no ENDED) before def makes it through the pipe:
$ (echo "abc"; sleep 5; echo "def") | bun test.js
Uint8Array(4) [ 97, 98, 99, 10 ]
$
I wonder this issue would also reproduce over large and/or slow file data :thinking:
Edit: for completeness:
$ (echo "abc"; sleep 0; echo "def") | bun test.js
Uint8Array(8) [ 97, 98, 99, 10, 100, 101, 102, 10 ]
undefined
ENDED
$
This has been fixed, tested as of Bun v1.0.7.