SocketCluster/writable-consumable-stream

Potential bug on multiple manual next()

Opened this issue · 0 comments

Hello, nice work on this lib. I like the linked list approach.
I think I found a bug though, an implementation details that prevents doing "bulk reads" of the stream.

import it from 'ava'

import WCS from 'writable-consumable-stream'

it('will probably fail', async t => {
  const stream = new WCS()
  const run = async () => {
    for (let i = 0; i < 5; i++) {
      await wait(10)
      stream.write('hello' + i)
    }
    stream.close()
  }

  const asyncIterator = stream.createConsumer()
  const receivedPackets = await Promise.all([
    asyncIterator.next(),
    asyncIterator.next(),
    asyncIterator.next(),
    asyncIterator.next(),
    asyncIterator.next(),
  ])
  await run()

  t.is(receivedPackets.length, 5)
  t.is(Object.keys(stream._consumers).length, 0) // Check internal cleanup.
})

This is because the next method of the consumer will happily replace the internal _resolve each time it is called. So the previous next calls never get a chance to be resolved and are just lost forever.