gRPC Timeouts & Deadlines

First, let’s figure out how the timeout differs from the deadline.

Timeout is relative value, but deadline is absolute. If we take a timeout and a deadline of 5 seconds, and we will write the following line (the code for an example, it will not work if you run it):

Operation operation = new Operation();
operation.deadline(5000, TimeUnit.MILLISECONDS);
Thread.sleep(4000);
operation.run();

Then, if you want to know your deadline time, you need mentally take time while you calling deadline() method and add value you specified in deadline() method (it is 5 seconds) to it. This value will be the deadline time for operation. For example, if the line:

operation.deadline(5, TimeUnit.SECONDS);

completed at 10:00:00, then the operation deadline will be at 10:00:05.

Then we wait 4 seconds:

Thread.sleep(4000);

And it turns out that to perform the operation:

operation.run();

There will be only 1 second left.

Timeouts work differently. This is a relative value, the counting of which will begin only during the execution of the operation itself:

operation.run();

This is how deadlines differs timeouts in gRPC.

There are three main cases in gRPC where we use timeouts / deadlines on the client side:

  • Timeout when creating a channel to a server
  • Deadline for the execution of the request by the server
  • Timeout when channel shutdown

Creating channel timeout (first point)

Please note that this is a timeout, not a deadline. It is set in this way:

ManagedChannel channel = NettyChannelBuilder.forAddress(host, port)
        .withOption(ChannelOption.CONNECT_TIMEOUT_MILLIS, 5000)
        .usePlaintext()
        .build();

This means that if within 5 seconds we failed to connect to the server, there will be an error.

Request deadline execution (second point)

Please note, this is a deadline. Therefore, it is very important to call the remote method IMMEDIATELY AFTER specifying withDeadlineAfter(). That is, first we made a stub:

ServiceGrpc.ServiceGrpcBlockingStub stub = ServiceGrpc.newBlockingStub(channel);

And then we called it with the withDeadlineAfter() method and immediately specified the remote method that we need to call:

stub.withDeadlineAfter(30000, TimeUnit.MILLISECONDS)
        .yourRpcMethod(YourRequest);

It turns out that the request will abort 30 seconds after the call withDeadlineAfter().

If you call the withDeadlineAfter() method when creating a stub, and something happens between the creation and use of the stub, then you will have LESS time to complete the operation than the specified deadline.

Close channel timeout (third point)

In the last article I wrote that if we create a channel, then we must close it after use. Also it is important to wait until the channel closes:

channel.shutdown();
try {
    channel.awaitTermination(5000, TimeUnit.MILLISECONDS);
} catch (InterruptedException ex) {
    log.error("gRPC channel shutdown interrupted");
}

Please note that this is a timeout.

If you still have any questions, feel free to ask me in the comments under this article, or write me on promark33@gmail.com.

If I saved your day, you can support me :)

Leave a Reply

Your email address will not be published.