node-pg-query-stream icon indicating copy to clipboard operation
node-pg-query-stream copied to clipboard

Stream not closed if for:await loop break

Open matthieusieben opened this issue 5 years ago • 1 comments

Considering the first utility (that yields the first result and then breaks):

import { fist } from 'axax/esnext/first'

async function* toAsyncIterable(conn, config) {
  const stream = conn.query(new QueryStream(config.text, config.values))
  return yield* stream // It's ok, stream.Readable has an [Symbol.asyncIterator] method
}

await first(toAsyncIterable(conn, 'SELECT * FROM some_table_with_more_than_one_entry'))

Doing so will result in the connection being stuck because the cursor was never closed.

My current workaround:

import { fist } from 'axax/esnext/first'

async function queryStream(conn, config) {
  const stream = conn.query(new QueryStream(config.text, config.values))
  try {
    return yield* stream
  } finally {
    // This will be called when iterator.return() is called
    stream.close()
  }
}

await first(toAsyncIterable(conn, 'SELECT * FROM some_table_with_more_than_one_entry'))

I believe that internally, node will wall the "destroy" method of the stream once the iterator consumer stops requesting output.

matthieusieben avatar Nov 13 '19 14:11 matthieusieben

Fixed in implementation here: https://github.com/brianc/node-pg-query-stream/issues/52#issuecomment-561644112

matthieusieben avatar Dec 04 '19 13:12 matthieusieben