@@ -3,7 +3,7 @@ var Module = require('module');
33import * as path from 'path' ;
44import * as http from 'http' ;
55import * as stream from 'stream' ;
6- import { AddressInfo } from 'net' ;
6+ import { AddressInfo , Socket } from 'net' ;
77import InvocationRequest from '../../../InvocationData/InvocationRequest' ;
88import ModuleSourceType from '../../../InvocationData/ModuleSourceType' ;
99
@@ -26,9 +26,29 @@ let projectDir = process.cwd();
2626// Create server
2727const server = http . createServer ( serverOnRequestListener ) ;
2828
29- // In Node.js v13+ this is the default, however for earlier versions it is 120 seconds.
29+ // The timeouts below are designed to manage network instability. Since we're using the HTTP protocol on a local machine, we can disable them
30+ // to avoid their overhead and stability issues.
31+
32+ // By default, on older versions of Node.js, request handling times out after 120 seconds.
33+ // This timeout is disabled by default on Node.js v13+.
34+ // Becuase of the older versions, we explicitly disable it.
3035server . setTimeout ( 0 ) ;
3136
37+ // By default, a socket is destroyed if it receives no incoming data for 5 seconds: https://nodejs.org/api/http.html#http_server_keepalivetimeout.
38+ // This is good practice when making external requests because DNS records may change: https://github.com/dotnet/runtime/issues/18348.
39+ // Since we're using the HTTP protocol on a local machine, it's safe and more efficient to keep sockets alive indefinitely.
40+ server . keepAliveTimeout = 0 ;
41+
42+ // By default, a socket is destroyed if its incoming headers take longer than 60 seconds: https://nodejs.org/api/http.html#http_server_headerstimeout.
43+ // In early versions of Node.js, even if setTimeout() was specified with a non-zero value, the server would wait indefinitely for headers.
44+ // This timeout was added to deal with that issue. We specify setTimeout(0), so this timeout is of no use to us.
45+ //
46+ // Note that while 0 disables this timeout in node 12.17+, in earlier versions it causes requests to time out immediately, so set to 10 years.
47+ server . headersTimeout = 10 * 365 * 24 * 60 * 60 * 1000 ;
48+
49+ // Log timed out connections for debugging
50+ server . on ( 'timeout' , serverOnTimeout ) ;
51+
3252// Send client error details to client for debugging
3353server . on ( 'clientError' , serverOnClientError ) ;
3454
@@ -182,6 +202,12 @@ function serverOnClientError(error: Error, socket: stream.Duplex) {
182202 socket . end ( httpResponseMessage ) ;
183203}
184204
205+ // Send timeout details to client for debugging - this shouldn't fire but there have been various node http server timeout issues in the past.
206+ // The socket won't actually get closed (the timeout function needs to do that manually).
207+ function serverOnTimeout ( socket : Socket ) {
208+ console . error ( `Ignoring unexpected socket timeout for address ${ socket . remoteAddress } , port ${ socket . remotePort } ` ) ;
209+ }
210+
185211function serverOnListeningListener ( ) {
186212 // Signal to HttpNodeHost which loopback IP address (IPv4 or IPv6) and port it should make its HTTP connections on
187213 // and that we are ready to process invocations.
0 commit comments