Default values sent by third party clients fails in rpc-server.
See original GitHub issueI create a protocol.proto
file with a numeric type in a message
syntax = "proto3";
package rpc.pkg;
message HelloRequest {
float name = 1;
}
message HelloResponse {
string message = 1;
}
service Greeter {
rpc SayHello (HelloRequest) returns (HelloResponse);
}
but server throws the following error while calling from a grpc client:
Apr 25, 2019 12:12:26 PM io.grpc.internal.SerializingExecutor run
SEVERE: Exception while executing runnable io.grpc.internal.ServerImpl$JumpToApplicationThreadServerStreamListener$1MessagesAvailable@5544a4d2
java.util.NoSuchElementException: head of empty list
at scala.collection.immutable.Nil$.head(List.scala:426)
at scala.collection.immutable.Nil$.head(List.scala:423)
at pbdirect.PBParserImplicits.$anonfun$requiredParser$1(PBReader.scala:173)
at pbdirect.PBParserImplicits.$anonfun$requiredParser$1$adapted(PBReader.scala:162)
at pbdirect.LowPriorityPBParserImplicits$$anon$2.parse(PBReader.scala:119)
at pbdirect.LowPriorityPBParserImplicits.$anonfun$consParser$1(PBReader.scala:128)
at pbdirect.LowPriorityPBParserImplicits.$anonfun$consParser$1$adapted(PBReader.scala:127)
at pbdirect.LowPriorityPBParserImplicits$$anon$2.parse(PBReader.scala:119)
at pbdirect.PBReaderImplicits.$anonfun$prodReader$1(PBReader.scala:62)
at pbdirect.LowerPriorityPBReaderImplicits$$anon$1.read(PBReader.scala:38)
at pbdirect.PBParserImplicits.$anonfun$requiredParser$1(PBReader.scala:169)
at pbdirect.PBParserImplicits.$anonfun$requiredParser$1$adapted(PBReader.scala:162)
at pbdirect.LowPriorityPBParserImplicits$$anon$2.parse(PBReader.scala:119)
at pbdirect.package$PBParserOps$.pbTo$extension(package.scala:47)
at higherkindness.mu.rpc.internal.encoders.pbd$$anon$1.parse(pbd.scala:40)
at io.grpc.MethodDescriptor.parseRequest(MethodDescriptor.java:289)
at io.grpc.internal.ServerCallImpl$ServerStreamListenerImpl.messagesAvailable(ServerCallImpl.java:263)
at io.grpc.internal.ServerImpl$JumpToApplicationThreadServerStreamListener$1MessagesAvailable.runInContext(ServerImpl.java:687)
at io.grpc.internal.ContextRunnable.run(ContextRunnable.java:37)
at io.grpc.internal.SerializingExecutor.run(SerializingExecutor.java:123)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Issue Analytics
- State:
- Created 4 years ago
- Comments:8 (6 by maintainers)
Top Results From Across the Web
Windows Server Troubleshooting: RPC server is unavailable
Introduction; The RPC Server; The RPC Client; RPC Quick Fixes. Unable to resolve DNS or NetBIOS names in an Active Directory environment.
Read more >The RPC server is unavailable. 0x800706BA
RPC errors are usually caused by an incorrect firewall setup on the client machine or the machine being offline, but can be caused...
Read more >Troubleshooting "RPC Server Unavailable" Errors | Dell US
This article discusses the solutions for error "RPC Server Unavailable" in Windows server operating systems.
Read more >Troubleshooting 'RPC server is unavailable' error in WIndows
In such cases, a client fails to send out a procedural call to the server resulting in the “RPC server unavailable” error.
Read more >FIX: 'The RPC Server is Unavailable' Outlook error
'The RPC server is unavailable' is a simple error that you may face while using Outlook or any other Windows service on a...
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 Free
Top 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
After initial investigation, the issue is acutally slightly wider than this:
The above request only fails in
grpcurl
when the message contains the default value. Sendinggo/bin/grpcurl -plaintext -import-path $PATH_TO_PROTO_DIR -proto protocol.proto -d '{"name":1}' 127.0.0.1:8000 Greeter.SayHello
- where thename
field is not zero - results in a successful response.This appears to be the same for all default values I tried, not just numeric ones, for instance, sending the empty string
""
fails too where a non-empty string is fine.Comparing the payload that
grpcurl
and mu client send to the server, it would appear that in the default case,grpcurl
does not actually send the value and expects the server to understand it needs to fill it in, but the mu client sends the value. Considering the server is not expecting an empty value to fill in itself, this is what causes the “head of empty list” exception.I’m currently familiarising myself with the protocol and what actually needs to be sent, and the best approach for the server to understand it needs to be able to handle default values.
Per the proto3 specification, all fields are now optional. During deserialization, if a field is absent on the wire, it is assigned a default value (empty string for
string
fields,0
for numeric fields, etc.) Conversely, when a field is assigned the default value, it is not serialized on the wire. That’s why the value of the field matters to reproduce this issue.pbdirect
probably doesn’t implement that part of the specification.