|
125 | 125 | // Signal to the NodeServices base class that we're ready to accept invocations |
126 | 126 | console.log('[Microsoft.AspNetCore.NodeServices:Listening]'); |
127 | 127 | }); |
128 | | - ExitWhenParentExits_1.exitWhenParentExits(parseInt(parsedArgs.parentPid)); |
| 128 | + ExitWhenParentExits_1.exitWhenParentExits(parseInt(parsedArgs.parentPid), /* ignoreSigint */ true); |
129 | 129 | function readRequestBodyAsJson(request, callback) { |
130 | 130 | var requestBodyAsString = ''; |
131 | 131 | request.on('data', function (chunk) { requestBodyAsString += chunk; }); |
|
255 | 255 | */ |
256 | 256 | "use strict"; |
257 | 257 | var pollIntervalMs = 1000; |
258 | | - function exitWhenParentExits(parentPid) { |
| 258 | + function exitWhenParentExits(parentPid, ignoreSigint) { |
259 | 259 | setInterval(function () { |
260 | 260 | if (!processExists(parentPid)) { |
261 | 261 | // Can't log anything at this point, because out stdout was connected to the parent, |
262 | 262 | // but the parent is gone. |
263 | 263 | process.exit(); |
264 | 264 | } |
265 | 265 | }, pollIntervalMs); |
| 266 | + if (ignoreSigint) { |
| 267 | + // Pressing ctrl+c in the terminal sends a SIGINT to all processes in the foreground process tree. |
| 268 | + // By default, the Node process would then exit before the .NET process, because ASP.NET implements |
| 269 | + // a delayed shutdown to allow ongoing requests to complete. |
| 270 | + // |
| 271 | + // This is problematic, because if Node exits first, the CopyToAsync code in ConditionalProxyMiddleware |
| 272 | + // will experience a read fault, and logs a huge load of errors. Fortunately, since the Node process is |
| 273 | + // already set up to shut itself down if it detects the .NET process is terminated, all we have to do is |
| 274 | + // ignore the SIGINT. The Node process will then terminate automatically after the .NET process does. |
| 275 | + // |
| 276 | + // A better solution would be to have WebpackDevMiddleware listen for SIGINT and gracefully close any |
| 277 | + // ongoing EventSource connections before letting the Node process exit, independently of the .NET |
| 278 | + // process exiting. However, doing this well in general is very nontrivial (see all the discussion at |
| 279 | + // https://github.com/nodejs/node/issues/2642). |
| 280 | + process.on('SIGINT', function () { |
| 281 | + console.log('Received SIGINT. Waiting for .NET process to exit...'); |
| 282 | + }); |
| 283 | + } |
266 | 284 | } |
267 | 285 | exports.exitWhenParentExits = exitWhenParentExits; |
268 | 286 | function processExists(pid) { |
|
0 commit comments