Streaming query result

I know I will never write a post on this, really, not a complete post on this matter. But I am working on making service consume less memory, and for sure I will achieve that.

By now this is just an idea of the result of the same request made by buffering a whole result set VS streaming out result as soon it comes from database

Stream version VS buffered version

As of now difference in time is less than 2 seconds, but a big difference in memory usage (about 300MB VS 30MB), and this is sending 8300 records.

This tests are done with NodeJS service (v18.10.0), fastify stream (4.9.2 https://fastify.io/), node-mysql2 module (v2.3.3 https://www.npmjs.com/package/mysql2), objstream ( https://www.npmjs.com/package/objstream because fastify reply.send() accepts a stream of bytes, no object mode).

The code is just a bit more complicated, but not too much

const streamResult = async (pool, request, reply) => {
  const {query, data} = request.body;
  const getPrepared = (query,data) => {...
  const {prepared, params} = getPrepared(query,data);
  
  return new Promise((resolve, reject) => {
    
    pool.getConnection( (err, conn) => {
      if(err) {
        throw new Error(err);
      }
      let transform = new ObjStream();

      let outStream = conn.execute({sql: prepared, rowsAsArray: true}, params).stream();
      
      let piped = outStream.pipe(transform)
      reply.send(piped);
      piped.on('error', (err)=> {
        reject(err);
        pool.releaseConnection(conn);
      });
      piped.on('finish', ()=> {
        pool.releaseConnection(conn);
        console.log("out stream finish");
        resolve(1)
      });
      
    })
  });
  
}

fastify.post('/sql-stream', async (req,reply) => {
    try {
        await streamResult(pool, req, reply);
        printUsage();
        console.log("END");
    } catch (err) {
        console.log("STREAM error:", err);
        reply.send({error: true});
    }
})

I will never finish to write this …

Actually in streamed version I am using rowsAsArray option true, switching to false things get worse in term of time to serve, memory consumption stay stable anyway.

Also I am not sure about the node module, and the code is so small that I should have the opportunity to rewrite it with rocket something, I think, still using stream.

Disappointed by @fastify/compress

I am just a bit disappointed by the unfulfilled promise of fastify/compress module, here:

https://github.com/fastify/fastify-compress#replycompress

There is an example of use of reply.compress(), sure, but no, that method does not exists.

It is strange, I look at the code, it should work, really, I am going to ask for some hint…

UPDATE: Clarification arrived from upstream dev about fastify and compress, in short time and well explained, rif. fastify 4 porting


Posted

in

by