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

streams: Writable expose needDrain #35341

Closed
ronag opened this issue Sep 25, 2020 · 3 comments
Closed

streams: Writable expose needDrain #35341

ronag opened this issue Sep 25, 2020 · 3 comments
Assignees
Labels
stream Issues and PRs related to the stream subsystem.

Comments

@ronag
Copy link
Member

ronag commented Sep 25, 2020

I have a case where it would make sense to expose needDrain on the public API.

This is when writing to a dst with retries:

Consider:

function send(src, dst, callback) {
  src.on('data', (buf) => {
    if (!dst.write(buf)) {
       src.pause()
    }
  }).on('end', () => {
    src.end()
    callback()
  }).on('error', (err) => {
    callback(err)
  }) 
}

Now consider the case where:

  • dst is paused
  • src fails due to a timeout (e.g. because dst is to slow to read)
  • the outer caller retries

Since we don't know whether to continue to write to dst until after we call dst.write() every retry will write more data that exceeds the HWM and eventually crashes the process in worst case.

For correctness IMO the above should look like this:

function send(src, dst, callback) {
  src.pause()
  if (src.needDrain) {
    src
      .on('error', err => callback(err))
      .on('drain', () => send(src, dst, callback)
    return
  }
  
  src.on('data', (buf) => {
    if (!dst.write(buf)) {
       src.pause()
    }
  }).on('end', () => {
    src.end()
    callback()
  }).on('error', (err) => {
    callback(err)
  }).resume() 
}

However, we currently don't have a needDrain property in the public API (and especially not OutgoingMessage where I encountered this problem).

@ronag ronag added the stream Issues and PRs related to the stream subsystem. label Sep 25, 2020
@ronag
Copy link
Member Author

ronag commented Sep 25, 2020

@nodejs/streams

@mcollina
Copy link
Member

I would call it writableNeedDrain. Overall, +1.

@ronag ronag self-assigned this Sep 25, 2020
@ronag
Copy link
Member Author

ronag commented Sep 25, 2020

Just a list of things that needs to be updated in this context:

  • pipeline
  • Readable.pipe
  • OutgoingMessage.writableNeedDrain
  • Writable.writableNeedDrain
  • Duplex.writableNeedDrain

@ronag ronag mentioned this issue Sep 25, 2020
4 tasks
ronag added a commit to nxtedition/node that referenced this issue Sep 25, 2020
Don't write to a stream which already has a full buffer.

Fixes: nodejs#35341
ronag added a commit to nodejs/undici that referenced this issue Sep 25, 2020
ronag added a commit to nodejs/undici that referenced this issue Sep 25, 2020
ronag added a commit to nodejs/undici that referenced this issue Sep 25, 2020
ronag added a commit to nodejs/undici that referenced this issue Sep 25, 2020
ronag added a commit to nodejs/undici that referenced this issue Oct 10, 2020
ronag added a commit to nodejs/undici that referenced this issue Oct 10, 2020
ronag added a commit to nodejs/undici that referenced this issue Nov 2, 2020
@aduh95 aduh95 closed this as completed in dd0f8f1 Nov 10, 2020
danielleadams pushed a commit that referenced this issue Nov 10, 2020
Don't write to a stream which already has a full buffer.

Fixes: #35341

PR-URL: #35348
Reviewed-By: Matteo Collina <[email protected]>
Reviewed-By: Luigi Pinca <[email protected]>
Reviewed-By: Benjamin Gruenbaum <[email protected]>
ronag added a commit to nodejs/undici that referenced this issue Nov 12, 2020
ronag added a commit to nodejs/undici that referenced this issue Nov 12, 2020
ronag added a commit to nodejs/undici that referenced this issue Nov 13, 2020
BethGriggs pushed a commit that referenced this issue Dec 9, 2020
Don't write to a stream which already has a full buffer.

Fixes: #35341

PR-URL: #35348
Reviewed-By: Matteo Collina <[email protected]>
Reviewed-By: Luigi Pinca <[email protected]>
Reviewed-By: Benjamin Gruenbaum <[email protected]>
targos pushed a commit that referenced this issue May 1, 2021
Don't write to a stream which already has a full buffer.

Fixes: #35341

PR-URL: #35348
Reviewed-By: Matteo Collina <[email protected]>
Reviewed-By: Luigi Pinca <[email protected]>
Reviewed-By: Benjamin Gruenbaum <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
stream Issues and PRs related to the stream subsystem.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants