brianc/node-pg-query-stream

Stream not closed if for:await loop break

matthieusieben opened this issue · 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.

Fixed in implementation here:
#52 (comment)