@grpc/grpc-js: sendUnaryData callback not working as expected
- Dominant language
- TypeScript
- Stars
- 4.8k
- Forks
- 716
- Avg merge
- 2d 3h
- Merged PRs (30d)
- 10
Description
### Problem description
When i call the sendUnaryData callback function of the request handler as soon as the request comes , the grpc client successfully gets the response.
When i am calling the callback function after awaiting for the result of a promise , the client call is not getting complete and response is not received.
### Reproduction steps :
Here's the below code for handling the request that doesn't send the response to the client :
```node
(clientCall: any, callback: grpc.sendUnaryData) => {
new Promise((res, rej)=>{
setTimeout(() => {
res({message : 'my response'})
}, 1000);
})
.then(responseInfo => {
console.log('calling response interceptor on : ', responseInfo);
return responseInfo
})
.then(responseInfo => {
console.log('sending transformed response : ', responseInfo);
callback(null,{message : 'its working'} )
});
};
```
Though the callback function gets called after 1 second , the response never reaches the client. Also the same behavior is seen even when i reduce the timeout to just "1 milli second" or even "0" .
#### Code that works :
The client successfully gets the response , if i resolve the promise outside the set timeout function.
```node
clientCall: any, callback: grpc.sendUnaryData) => {
new Promise((res, rej)=>{
res({message : 'my response'});
})
.then(responseInfo => {
console.log('calling response interceptor on : ', responseInfo);
return responseInfo
})
.then(responseInfo => {
console.log('sending transformed response : ', responseInfo);
callback(null,{message : 'its working'} )
});
};
```
if i change the code to the above code , then i get a proper response :
```
{
"message": "its working"
}
```
### Environment
- Linux pop-os 5.8.0-7625-generic
- Node version v10.19.0
- Package name and version "@grpc/grpc-js": "^1.2.2"
### Additional Context :
Here is the full enclosing function code that i am using ( may be helpful ? ) :
```node
function addGrpcServices(server: grpc.Server | null, serviceProtos: ProtoService[]): void {
serviceProtos.forEach(serviceProto => {
const serviceImplementation: grpc.UntypedServiceImplementation = {}
Object.entries(serviceProto.methods).forEach(([methodName, methodRpcInfo]) => {
serviceImplementation[methodName] = (clientCall: any, callback: grpc.sendUnaryData) => {
new Promise((res, rej) => {
setTimeOut( ()=>{
res({ message: 'my response' })
} , 1000);
})
.then(responseInfo => {
// i plan to add some console log and other stuff here later.
return responseInfo
})
.then(responseInfo => {
callback(null, { message: 'its working' })
});
};
})
server.addService(serviceProto.serviceDefinition, serviceImplementation);
})
}
export const startMockGrpcServer = (serviceProtos: ProtoService[]): void => {
const grpcServer = new grpc.Server();
addGrpcServices(grpcServer, serviceProtos)
appConfigStore.subscribe(config => {
grpcServer.bindAsync(config.mockGrpcServerUrl, grpc.ServerCredentials.createInsecure(), (error, port) => {
if (error) {
console.error(error)
}
else {
console.log("Started server at port : ", port)
grpcServer.start();
appConfigStore.setMockGrpcServer(grpcServer)
}
});
})();
}
```
Contributor guide
Assessment
This issue has not been assessed yet.