0

I am using a Mongoose cursor to retrieve a big amount of data in parts and send it progressively as I receive each part. To do this, I use the method res.write().

cursor.on('data', (doc) => {
  /*Array opening bracket only sent at the start*/
  if (total === 0) {
    res.write('[');
  }
  docs.push(doc);
  total += 1;

  /*Limit indicates each CSV length*/
  if (docs.length === limit) {
    res.write(JSON.stringify(docs));
    res.write(',');
    docs = [];
  }
});

cursor.on('end', (doc) => {
  ...
  /*Closing bracket sent after the array is completed*/
  res.write(']');
  ...
  res.end();
});

As seen in the code above, I have a variable limit to know when to write the next part of the response. If this variable is too big, it requires more time to assemble each part, and the query finishes before I could write it. (If I reduce this variable, it works fine).

When this happens, the response only contains the string: '['. As if it would have called the method res.end() after a certain amount of time.

My question is: Is there a timeout when you use the res.write() method, after which (if you don't keep writing or send the response) res.end() is called? Or am I missing something?

kuzyn
  • 1,905
  • 18
  • 30
  • `response.write` is a node.js method https://nodejs.org/api/http.html#http_response_write_chunk_encoding_callback – kuzyn Jul 12 '17 at 13:47

1 Answers1

0

There is no timeout for res.write. If you look at the doc however, while the headers are implicitly set the first time response.write is invoked, they might not be exactly what you want

I would try to explicitly set these headers before sending out data, i.e. when you receive the request:

response.setHeader('Connection', 'Transfer-Encoding');
response.setHeader('Content-Type', 'text/html; charset=utf-8');
response.setHeader('Transfer-Encoding', 'chunked');

I would also add a simple check to response.write to make sure that each chunk is flushed:

  /*Limit indicates each CSV length*/
  if (docs.length === limit) {
    let chunk = JSON.stringify(docs);
    if(res.write(`${chunk},`)) {
      docs = [];
    } else {
      console.log(`oops! something is wrong with chunk ${chunk}`);
    }
  }

Finally, I would read up this answer https://stackoverflow.com/a/16999405/3253893 to understand why this might be a bad idea if you expect more than one query at a time

kuzyn
  • 1,905
  • 18
  • 30