Skip to content
This repository has been archived by the owner on Apr 22, 2023. It is now read-only.

readable.unshift(chunk) not resetting state.reading #14604

Closed
zoubin opened this issue Apr 11, 2015 · 10 comments
Closed

readable.unshift(chunk) not resetting state.reading #14604

zoubin opened this issue Apr 11, 2015 · 10 comments

Comments

@zoubin
Copy link

zoubin commented Apr 11, 2015

I see it is done on purpose in readableAddChunk, but it confuses me. Especially when I find that the example given in the documentation fails because it does nothing to reset the reading flag (like push('')) after this.unshift(b).

Is it necessary to behave this way?

@jasnell
Copy link
Member

jasnell commented Jun 25, 2015

@trevnorris

@trevnorris
Copy link

Sorry. Don't fully understand the concern.

May also be advantageous to pull in @chrisdickinson

@jasnell
Copy link
Member

jasnell commented Jun 26, 2015

@trevnorris @chrisdickinson ... if I understand the original post correctly, the question is about why readable_stream.unshift does not cause readablestate.reading to be reset the way readable_stream.push does. See https://github.com/joyent/node/blob/master/lib/_stream_readable.js#L128 vs. https://github.com/joyent/node/blob/master/lib/_stream_readable.js#L134. The final argument to readableAddChunk is addToFront, the reading flag is only reset if addToFront is false. The original poster is looking to understand why that is.

@trevnorris
Copy link

Ah. Um, no idea. I think @isaacs was the one to implement that code.

@jasnell
Copy link
Member

jasnell commented Jun 26, 2015

@isaacs ... any chance you could help shed some light on this one?

@zoubin
Copy link
Author

zoubin commented Jun 26, 2015

@jasnell @trevnorris Thanks for response. Here is a more simple example to show my confusion:

var rs = require('stream').Readable({ objectMode: true })
var buffer = ['a', 'b']
var unshift = false

rs._read = function () {
  if (!unshift) {
    this.unshift('c') // this leaves rs._readableState.reading `true`
    unshift = true
    this.push('') // this makes rs._readableState.reading `false`
  }
  else {
    if (buffer.length) {
      this.push(buffer.pop())
    }
    else {
      this.push(null)
    }
  }
}

console.log('data:"' + rs.read() + '"')
console.log(rs._readableState.reading)
console.log('data:"' + rs.read() + '"')
console.log('data:"' + rs.read() + '"')
console.log('data:"' + rs.read() + '"')

output:

data:"c"
false
data:""
data:"b"
data:"a"

However, if we do not .push('') after .unshift('c'), rs._readableState.reading will be leaved true and the following three reads get nothing

output:

data:"c"
true
data:"null"
data:"null"
data:"null"

I believe that .unshift() not resetting state.reading makes .unshift() have to be followed by a .push() to make things work. Is it necessary?

@zoubin
Copy link
Author

zoubin commented Jun 26, 2015

Perhaps the example above does not use .unshift in the proper way.

The following case is more reasonable:

var rs = require('stream').Readable({ objectMode: true })
var buffer = ['a', 'b']
var unshift = false

rs._read = function () {
  if (buffer.length) {
    this.push(buffer.pop())
  }
  else {
    this.push(null)
  }
}

rs.on('data', function (chunk) {
  console.log(chunk)
  if (!unshift) {
    this.unshift('c')
    unshift = true
  }
})

output:

b
c
a

@jasnell
Copy link
Member

jasnell commented Jul 1, 2015

So does that resolve the issue for you @zoubin ?

@zoubin
Copy link
Author

zoubin commented Jul 2, 2015

@jasnell Almost. Thanks.

If we use stream.unshift() in stream._read, then each time we .unshift something, we have to .push(''). Right now I can remember this.

jasnell added a commit to jasnell/node-joyent that referenced this issue Jul 6, 2015
Per nodejs#14604,

Document that performing an `unshift` during a read
can have unexpected results. Following the `unshift`
with a `push('')` resets the reading state appropriately.
Also indicate that doing an `unshift` during a read
is not optimal and should be avoided.
@jasnell
Copy link
Member

jasnell commented Jul 6, 2015

Will have a pull request shortly that addresses this issue in documentation

jasnell added a commit that referenced this issue Jul 10, 2015
Per #14604,

Document that performing an `unshift` during a read
can have unexpected results. Following the `unshift`
with a `push('')` resets the reading state appropriately.
Also indicate that doing an `unshift` during a read
is not optimal and should be avoided.

Reviewed-By: James M Snell <jasnell@gmail.com>
PR-URL: #25635
@jasnell jasnell closed this as completed Jul 10, 2015
jasnell added a commit to jasnell/node-joyent that referenced this issue Jul 10, 2015
Per nodejs#14604,

Document that performing an `unshift` during a read
can have unexpected results. Following the `unshift`
with a `push('')` resets the reading state appropriately.
Also indicate that doing an `unshift` during a read
is not optimal and should be avoided.

Reviewed-By: James M Snell <jasnell@gmail.com>
PR-URL: nodejs#25635
jasnell added a commit that referenced this issue Aug 4, 2015
Per #14604,

Document that performing an `unshift` during a read
can have unexpected results. Following the `unshift`
with a `push('')` resets the reading state appropriately.
Also indicate that doing an `unshift` during a read
is not optimal and should be avoided.

Reviewed-By: James M Snell <jasnell@gmail.com>
PR-URL: #25591
jasnell added a commit to jasnell/node that referenced this issue Aug 4, 2015
Per nodejs/node-v0.x-archive#14604,

Document that performing an `unshift` during a read
can have unexpected results. Following the `unshift`
with a `push('')` resets the reading state appropriately.
Also indicate that doing an `unshift` during a read
is not optimal and should be avoided.

Reviewed-By: James M Snell <jasnell@gmail.com>
PR-URL: nodejs/node-v0.x-archive#25591
jBarz pushed a commit to ibmruntimes/node that referenced this issue Nov 4, 2016
Per nodejs#14604,

Document that performing an `unshift` during a read
can have unexpected results. Following the `unshift`
with a `push('')` resets the reading state appropriately.
Also indicate that doing an `unshift` during a read
is not optimal and should be avoided.

Reviewed-By: James M Snell <jasnell@gmail.com>
PR-URL: nodejs#25591
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants