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

Readline does not appear to fully parse long stdin streams when printing #8095

Closed
rgrannell1 opened this issue Aug 13, 2016 · 4 comments
Closed
Labels
readline Issues and PRs related to the built-in readline module.

Comments

@rgrannell1
Copy link

rgrannell1 commented Aug 13, 2016

  • Version:
  • Platform:
  • Subsystem:
  • node-version: 6.0.0
  • platform: Linux ryan-S400CA 4.4.0-34-generic [streams] _flush not being called #53-Ubuntu SMP Wed Jul 27 16:06:39 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux
  • subsystem: Readline, stream-handling

Observed Behaviour

readline.createInterface({input: process.stdin}) does not print each line and then emit the close event in a program designed to do this; instead it prints a random number of lines from stdin before exiting silently.

I'm unsure whether this is due to a misconception I have about the test-program, or whether this is a genuine bug. If any more information is needed, leave a comment and I'll respond quickly.

Expected Behaviour

readline should print each line from stdin, and then emit the close event.

Data

The program below tries to print each line of War and Peace (roughly 65,000 lines long), which it receives from stdin. When not printing, it always manages to emit the close event before exiting. When printing, the program exists prematurely after printing roughly 1900 lines.

1925
1947
65325
1936
1947
1925
65325
1936
65325
65325
65325
1936
65325
1936
1947
1925

Test Proceedure

  1. Download war and peace, as a text input file. Store it in ~/test-input.txt
  2. Save the following program to ~/test-program.js:
"use strict"




const path      = require('path')
const fs        = require('fs')
const readline  = require('readline')

const inputPath = path.join(process.env['HOME'], 'test-input.txt')
const lines     = fs.readFileSync(inputPath).toString( ).split('\n')

var counts = {
    expected: lines.length,
    actual:   0
}





function performTest (shouldPrint) {

    readline.createInterface({input: process.stdin})
    .on('line', line => {

        if (shouldPrint) {
            console.log(line)
        }
        counts.actual++

    })
    .on('close', ( ) => {
        throw new Error(JSON.stringify(counts))
    })

}

performTest(false)

  1. Run the following command from a unix OS (sorry about the useless use of cat, but its how I initially noticed the problem). Repeat several times:
cat ~/test-input.text | node ~/test-program.js

# EDIT: this behaves similarly 
node ~/test-program.js < ~/test-input.text 
        throw new Error(JSON.stringify(counts))
        ^

Error: {"expected":65326,"actual":65325}

You will repeatedly see an error showing the entire file was read.

  1. Replace
performTest(false)

with

performTest(true)

and rerun the test several times. The results should vary; on my machine it either prints out a line
~1900 lines into the file, or reaches the end of the file.

@mscdex mscdex added the readline Issues and PRs related to the built-in readline module. label Aug 13, 2016
@mscdex
Copy link
Contributor

mscdex commented Aug 13, 2016

I think this may have to do with writes to a tty being asynchronous in some cases. This was changed in ab3306a, which as of this writing hasn't been included in a release yet.

@rgrannell1
Copy link
Author

@mscdex Thanks for your response. Has this commit been added to Node.js yet?

@mscdex
Copy link
Contributor

mscdex commented Apr 22, 2017

@mscdex mscdex closed this as completed Apr 22, 2017
@rgrannell1
Copy link
Author

Thanks @mscdex, this test passes for me now

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
readline Issues and PRs related to the built-in readline module.
Projects
None yet
Development

No branches or pull requests

2 participants