Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 1c4682e

Browse filesBrowse files
Fix all the ConditionalProxyMiddleware errors that happened if you ctrl+c on a "dotnet run" (not "dotnet watch run") since beta-000002.
1 parent 6545e11 commit 1c4682e
Copy full SHA for 1c4682e

File tree

Expand file treeCollapse file tree

3 files changed

+42
-5
lines changed
Open diff view settings
Filter options
Expand file treeCollapse file tree

3 files changed

+42
-5
lines changed
Open diff view settings
Collapse file

‎src/Microsoft.AspNetCore.NodeServices/Content/Node/entrypoint-http.js‎

Copy file name to clipboardExpand all lines: src/Microsoft.AspNetCore.NodeServices/Content/Node/entrypoint-http.js
+20-2Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@
125125
// Signal to the NodeServices base class that we're ready to accept invocations
126126
console.log('[Microsoft.AspNetCore.NodeServices:Listening]');
127127
});
128-
ExitWhenParentExits_1.exitWhenParentExits(parseInt(parsedArgs.parentPid));
128+
ExitWhenParentExits_1.exitWhenParentExits(parseInt(parsedArgs.parentPid), /* ignoreSigint */ true);
129129
function readRequestBodyAsJson(request, callback) {
130130
var requestBodyAsString = '';
131131
request.on('data', function (chunk) { requestBodyAsString += chunk; });
@@ -255,14 +255,32 @@
255255
*/
256256
"use strict";
257257
var pollIntervalMs = 1000;
258-
function exitWhenParentExits(parentPid) {
258+
function exitWhenParentExits(parentPid, ignoreSigint) {
259259
setInterval(function () {
260260
if (!processExists(parentPid)) {
261261
// Can't log anything at this point, because out stdout was connected to the parent,
262262
// but the parent is gone.
263263
process.exit();
264264
}
265265
}, 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+
}
266284
}
267285
exports.exitWhenParentExits = exitWhenParentExits;
268286
function processExists(pid) {
Collapse file

‎src/Microsoft.AspNetCore.NodeServices/TypeScript/HttpNodeInstanceEntryPoint.ts‎

Copy file name to clipboardExpand all lines: src/Microsoft.AspNetCore.NodeServices/TypeScript/HttpNodeInstanceEntryPoint.ts
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ server.listen(requestedPortOrZero, 'localhost', function () {
7676
console.log('[Microsoft.AspNetCore.NodeServices:Listening]');
7777
});
7878

79-
exitWhenParentExits(parseInt(parsedArgs.parentPid));
79+
exitWhenParentExits(parseInt(parsedArgs.parentPid), /* ignoreSigint */ true);
8080

8181
function readRequestBodyAsJson(request, callback) {
8282
let requestBodyAsString = '';
Collapse file

‎src/Microsoft.AspNetCore.NodeServices/TypeScript/Util/ExitWhenParentExits.ts‎

Copy file name to clipboardExpand all lines: src/Microsoft.AspNetCore.NodeServices/TypeScript/Util/ExitWhenParentExits.ts
+21-2Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,14 +34,33 @@ to check whether the parent PID is still running. So that's what we do here.
3434

3535
const pollIntervalMs = 1000;
3636

37-
export function exitWhenParentExits(parentPid: number) {
37+
export function exitWhenParentExits(parentPid: number, ignoreSigint: boolean) {
3838
setInterval(() => {
3939
if (!processExists(parentPid)) {
4040
// Can't log anything at this point, because out stdout was connected to the parent,
4141
// but the parent is gone.
4242
process.exit();
4343
}
4444
}, pollIntervalMs);
45+
46+
if (ignoreSigint) {
47+
// Pressing ctrl+c in the terminal sends a SIGINT to all processes in the foreground process tree.
48+
// By default, the Node process would then exit before the .NET process, because ASP.NET implements
49+
// a delayed shutdown to allow ongoing requests to complete.
50+
//
51+
// This is problematic, because if Node exits first, the CopyToAsync code in ConditionalProxyMiddleware
52+
// will experience a read fault, and logs a huge load of errors. Fortunately, since the Node process is
53+
// already set up to shut itself down if it detects the .NET process is terminated, all we have to do is
54+
// ignore the SIGINT. The Node process will then terminate automatically after the .NET process does.
55+
//
56+
// A better solution would be to have WebpackDevMiddleware listen for SIGINT and gracefully close any
57+
// ongoing EventSource connections before letting the Node process exit, independently of the .NET
58+
// process exiting. However, doing this well in general is very nontrivial (see all the discussion at
59+
// https://github.com/nodejs/node/issues/2642).
60+
process.on('SIGINT', () => {
61+
console.log('Received SIGINT. Waiting for .NET process to exit...');
62+
});
63+
}
4564
}
4665

4766
function processExists(pid: number) {
@@ -56,7 +75,7 @@ function processExists(pid: number) {
5675
if (ex.code === 'EPERM') {
5776
throw new Error(`Attempted to check whether process ${pid} was running, but got a permissions error.`);
5877
}
59-
78+
6079
return false;
6180
}
6281
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.