@grpc/grpc-js: tryShutdown freeze app
See original GitHub issueProblem description
If client crashes or exits before server calls call.end()
, server.tryShutdown(callback)
freezes app. Server has http2session which is closed, so maybeCallback
doesn’t decrement pendingChecks
, and callback
is never called (if tryShutdown was promisified it never resolves).
Reproduction steps
Create server-side stream (hellostreamingworld.proto), end client app before server calls call.end()
.
(client - greater_client.js without changes)
const promisify = require("util").promisify;
const log = require('why-is-node-running');
var messages = require('./hellostreamingworld_pb');
var services = require('./hellostreamingworld_grpc_pb');
var grpc = require('@grpc/grpc-js');
function sayHello(call) {
var num = call.request.getNumGreetings();
console.log(call.request.toObject());
console.log(`${num} greetings`);
function greet() {
if (num-- < 0) {
return;
}
var reply = new messages.HelloReply();
reply.setMessage('Hello ' + call.request.getName());
call.write(reply);
setTimeout(greet, 2000);
}
setTimeout(greet, 1000);
call.end();
}
async function main() {
var server = new grpc.Server();
server.addService(services.MultiGreeterService, {sayHello: sayHello});
await promisify(server.bindAsync.bind(server))('0.0.0.0:50051', grpc.ServerCredentials.createInsecure());
server.start();
setTimeout(() => {
console.log('start server shutdown');
setTimeout(log, 10000);
server.tryShutdown(() => {
console.log("server shutdown");
});
}, 10000);
}
main();
Environment
- OS name, version and architecture: ArchLinux x86_64
- Node version: v12.18.0
- Node installation method: nvm
- Package name and version [e.g. “@grpc/grpc-js”: “^0.6.16”]
Additional information
server output:
{ name: 'world', numGreetings: 10 }
10 greetings
start server shutdown
There are 8 handle(s) keeping the process running
# TTYWRAP
/home/maxim/code/grpc/examples/node/node_modules/grpc/node_modules/set-blocking/index.js:2 - [process.stdout, process.stderr].forEach(function (stream) {
/home/maxim/code/grpc/examples/node/node_modules/grpc/node_modules/npmlog/log.js:11 - setBlocking(true)
# SIGNALWRAP
/home/maxim/code/grpc/examples/node/node_modules/grpc/node_modules/set-blocking/index.js:2 - [process.stdout, process.stderr].forEach(function (stream) {
/home/maxim/code/grpc/examples/node/node_modules/grpc/node_modules/npmlog/log.js:11 - setBlocking(true)
# TTYWRAP
/home/maxim/code/grpc/examples/node/node_modules/grpc/node_modules/set-blocking/index.js:2 - [process.stdout, process.stderr].forEach(function (stream) {
/home/maxim/code/grpc/examples/node/node_modules/grpc/node_modules/npmlog/log.js:11 - setBlocking(true)
# DNSCHANNEL
(unknown stack trace)
# HTTP2SESSION
(unknown stack trace)
# HTTP2SETTINGS
(unknown stack trace)
# Timeout
/home/maxim/code/grpc/examples/node/static_codegen/greeter_server.js:55 - setTimeout(log, 10000);
# Timeout
/home/maxim/code/grpc/examples/node/static_codegen/greeter_server.js:38 - setTimeout(greet, 2000);
Issue Analytics
- State:
- Created 3 years ago
- Reactions:2
- Comments:9 (7 by maintainers)
Top Results From Across the Web
node js grpc server forceShutdown doesn't shut down properly
It seems like a bug on gRPC's part. According to their docs: When it returns, the server has shut down. Meaning that when...
Read more >Long cold start times for Node.js programs with gRPC ...
I have an application running in nodejs 10. I am using cloud functions, I am finishing the test period, so it is still...
Read more >Deploy a gRPC-based application on an Amazon EKS cluster ...
This pattern describes how to host a gRPC-based application on an Amazon Elastic Kubernetes Service (Amazon EKS) cluster and securely access it through...
Read more >Implementing Graceful Shutdown in Go | RudderStack Blog
This post details the implementation of graceful shutdown on Rudder Server. ... Let's try to fix this problem by introducing context.
Read more >gRPC Load Balancing on Kubernetes without Tears
js microservices app and deploy it on Kubernetes: While the voting service displayed here has several pods, it's clear from Kubernetes's CPU ...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
I’m facing a similar problem, but
tryShutdown
doesn’t ever finish when the only thing I’ve done is to create a duplex stream, and then end it from both sides. Both sides report that the stream is destroyed, the client is closed, but then the server continues to wait to shutdown. I have to force shutdown. Seems thetryShutdown
is a bit flaky?I was able to get some logs by setting the environment variables
GRPC_TRACE=all
andGRPC_VERBOSITY=DEBUG
when running that test. According to those logs, the client opens two streams, and the second one finishes, but the first one never does. It is intended behavior that the server does not call the callback fortryShutdown
until all streams have finished. If you want to force the server to shut down you should callforceShutdown
.In the PR you linked, you are awaiting the result of
tryShutdown
on line 184. The code will not progress past that point until the server has finished shutting down, so it never actually callsforceShutdown
on line 191. If you remove the call toawait
on line 184 that will probably fix it.