Better documentation on tonic::transport::Server::.timeout function
Hello,
I have spent some time digging through the implementation to discover the following:
- What is the default timeout if no timeout is set (I see that the default value is None, but what does that mean (a fixed timeout, no timeout, ... ?)
- What does this timeout mean? My understanding is that this regulates the amount of time a given request has to executer, after which it will be dropped. Is this true?
I ask this specifically because by looking for help on this topic I read elsewhere that Tonic server wouldn't have a timeout functionality because this could be controlled by clients, but now I see that this functionality does exist.
btw: muy understanding is that once a graceful shutdown future completes, in-flight requests will complete (respecting this timeout setting) and then the server will stop. Is this assumption correct?
It would be nice to document these behaviors so that others can find this information more quickly.
Thanks, Marlon
I also wanted to know the answers to these questions, so I did some digging. However, I didn't have any prior knowledge on tonic's timeouts or shutdown logic, so take this with a grain of skeptical salt.
What is the default timeout if no timeout is set
The shorter of the client timeout (specified via grpc-timeout) and the configured server timeout is used. The default is None, so it looks like that means that (assuming the client doesn't specify a timeout) the default is no timeout.
What does this timeout mean?
If the request handler doesn't respond within the timeout, a TimeoutExpired error is returned.
Here's an example of what that looks like:
Status {
code: Cancelled,
message: "Timeout expired",
metadata: MetadataMap {
headers: {"date": "Thu, 23 Jun 2022 11:49:52 GMT"}
},
source: None
}
You can test this for yourself by specifying a timeout of a single nanosecond or something equally impossible.
If you're curious, here's what it looks like if you specify the timeout via tower instead of tonic's transport module (which is shown above):
Status {
code: Unknown,
message: "transport error",
source: Some(
tonic::transport::Error(
Transport,
hyper::Error(Http2, Error {
kind: Reset(
StreamId(1),
INTERNAL_ERROR,
Remote
)
})
)
)
}
Note that it appears as though timeouts only apply to individual handler invocations and not to streaming requests/responses. This appears to be the case for both tonic::transport::server::Server::timeout and tower::timeout. I'm not sure if this is a bug or expected behavior (maybe @davidpdrsn can comment on this?), but either way, I'd like a way to specify a timeout for streams as well.
once a graceful shutdown future completes, in-flight requests will complete (respecting this timeout setting) and then the server will stop
Yes, but see the previous note about streaming requests/responses not respecting timeouts. tonic just delegates to hyper's graceful_shutdown, which drains active connections (including streaming ones) before shutting down.