Skip to content

http2: fix several timeout related issues

This resolves a couple of issues around timeouts in http2.

  1. Upon start and stop of write, _unrefActive should be called both on stream and on session. I can't really create a good test case for this because it's way too reliant on timers. One can observe this by having a server receive a request, have a timeout of 1000ms on the session and delay the stream response (which has to last longer than 500ms) by 500ms. The session will timeout 500ms after the stream write starts (instead of 1000ms).

  2. Long writes will always timeout because once the data is handed off to C++, JS loses all track of it. This is basically the same issue as the one recently patched in net & tls. Solution is a bit different because tracking writeQueueSize in C++ is not quite reliable due to framing headers and what not.

(Much like with tls/net, the solution isn't super straightforward because we don't want to completely tank the performance of requests that aren't likely to timeout.)

To test locally, you can use the following server:

'use strict';

const http2 = require('http2');

const server = http2.createServer((req, res) => {

  var content = Buffer.alloc(30000000, 0x44);

  res.writeHead(200, {
    'Content-Type': 'application/octet-stream',
    'Content-Length': content.length.toString(),
    'Vary': 'Accept-Encoding'
  });

  res.write(content);
  res.end();
});
server.setTimeout(1000);

server.listen(8000);

and run this in your terminal:

nghttp http://localhost:8000 | dd bs=1 of=/dev/null

A successful result would be 30000000+0 records in (and take around 40s) but it'll stop after only 1s with current versions of node.

Checklist
  • make -j4 test (UNIX), or vcbuild test (Windows) passes
  • tests and/or benchmarks are included
  • commit message follows commit guidelines
Affected core subsystem(s)

http2, test

Merge request reports

Loading