zlib freezing the node event loop

Viewed 196

I can across a problem where my promisified zlib.gunzip would start eating up all the CPU and causing my instances to become unresponsive (I checked the Event Loop Lag and it would sometimes be insanely high). From what I read, zlib is using the worker threads so I never thought that was the problem. The code looks like:

const util = require('util');
const zlib = require('zlib');

const gunzip = util.promisify(zlib.gunzip);

const fetchData = async (url) => {
  const response = await request({
    url,
    encoding: null,
    resolveWithFullResponse: true
  });

  // External service is sometimes returning 200 with HTML when rate limiting
  if (response.headers['content-type'] === 'text/html; charset=UTF-8') {
    response.statusCode = 500;
    throw new ServiceError('External service error');
  }

  return gunzip(response.body);
};

The external provider allows for gzipped and text (UTF-8) responses. As soon as I switched to the text version, the CPU usage went from 100% to 10% in production (with maybe 3-4 QPS). Thing is, most of the time I have to throw my ServiceError because I am being rate limited and the zlib code path is not executed in that case, but the CPU was still choking.

Any idea why that is the case? Am I forgetting something that might cause calls to be sync or block the event loop?

EDIT 1: I realized the problem only occurs when something throws in the method. Otherwise it is working as expected.

0 Answers
Related