Skip to content

docs: writable streams from async iterators example issue #31365

Description

@ronag

Continuation of #31222

Further issues with the example. See comment:

async function pump(iterable, writable) {
  for await (const chunk of iterable) {
    // Handle backpressure on write().
    if (!writable.write(chunk)) {
      if (writable.destroyed) return;
      await once(writable, 'drain'); // BUG? This will never complete if writable is destroyed with `.destroy()`.
    }
  }
  writable.end();
}

The problem here is that it assumes that either 'drain' or 'error' will be emitted, however this is not always the case.

Activity

  1. ronag commented on Jan 15, 2020

    @ronag
    MemberAuthor
  2. ronag commented on Jan 15, 2020

    @ronag
    MemberAuthor

    These are the solutions I can think of at the moment:

    1. Have destroy() emit a 'drain' before 'close' if needDrain === true.

    await Promise.all([
      await once(writable, 'drain')
      await once(writable, 'close')
    ]);
    1. Have Writable emit premature close error if .destroy() is called before 'finish'
  3. mcollina commented on Jan 15, 2020

    @mcollina
    SponsorMember

    See openjs-foundation/summit#216 (comment) and the rest of the thread.

    I think we should add a promisified write.

    cc @benjamingr @apapirovski @davidmarkclements

  4. ronag commented on Jan 15, 2020

    @ronag
    MemberAuthor

    I think we should add a promisified write.

    Maybe remove this await once(writable, 'drain') example then? Since it is possibly broken.

  5. ronag commented on Jan 15, 2020

    @ronag
    MemberAuthor

    See openjs-foundation/summit#216 (comment) and the rest of the thread.

    This example has the same problem though... 'drain' might not be emitted.

    EDIT: I think most of the suggestions in that thread have the same problem in assuming that either 'error' or 'drain' will be emitted if needDrain.

  6. mcollina commented on Jan 15, 2020

    @mcollina
    SponsorMember

    We might have to listen for 'finish' as well. Would you mind to send a PR to add that? I think it would fix the issue.

  7. ronag commented on Jan 15, 2020

    @ronag
    MemberAuthor

    Do we and/or should we emit 'finish' when abruptly closing a writable with .destroy()? i.e. should end() and destroy() mean the same thing for a Writable?

    I guess we should in order to not break... since we don't error it in this case. Just seems a little weird.

    I think I would have preferred the "Have Writable emit premature close error if .destroy() is called before 'finish'" option. Though that's probably to breaking.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions