Skip to content

Commit

Permalink
gRPC timeout and deadlines
Browse files Browse the repository at this point in the history
  • Loading branch information
vietj committed Nov 14, 2024
1 parent b875765 commit 6490518
Show file tree
Hide file tree
Showing 5 changed files with 198 additions and 0 deletions.
16 changes: 16 additions & 0 deletions grpc-examples/README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,22 @@ You can run the server and then run the client.

You can read more about it on the http://www.grpc.io/docs/quickstart/java.html[gRPC website]

== Timeout and deadlines

The Hello World example showing timeout and deadlines in action.

The server is configured to create a deadline when a request with a timeout is received.

It does not send a response purposely to trigger this deadline based on the request timeout.

link:src/main/java/io/vertx/example/grpc/deadline/Server.java[gRPC server example]
link:src/main/java/io/vertx/example/grpc/deadline/ServerWithStub.java[gRPC server stub example]

The client is configured to set a request with a timeout and rely on the server to respond with a deadline exceeded status.

link:src/main/java/io/vertx/example/grpc/deadline/Client.java[gRPC client example]
link:src/main/java/io/vertx/example/grpc/deadline/ClientWithStub.java[gRPC client stub example]

== JSON wire format

The Hello World example using JSON wire format instead of Protobuf.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package io.vertx.example.grpc.deadline;

import io.grpc.examples.helloworld.HelloReply;
import io.grpc.examples.helloworld.HelloRequest;
import io.grpc.examples.helloworld.VertxGreeterGrpcClient;
import io.vertx.core.Future;
import io.vertx.core.VerticleBase;
import io.vertx.core.net.SocketAddress;
import io.vertx.grpc.client.GrpcClient;
import io.vertx.grpc.client.GrpcClientOptions;
import io.vertx.grpc.common.GrpcReadStream;
import io.vertx.launcher.application.VertxApplication;

import java.util.concurrent.TimeUnit;

/**
* @author <a href="mailto:[email protected]">Julien Viet</a>
*/
public class Client extends VerticleBase {

public static void main(String[] args) {
VertxApplication.main(new String[]{Client.class.getName()});
}

private GrpcClient client;

@Override
public Future<?> start() throws Exception {
client = GrpcClient.client(vertx, new GrpcClientOptions()
.setTimeout(5)
.setTimeoutUnit(TimeUnit.SECONDS));
return client.request(SocketAddress.inetSocketAddress(8080, "localhost"), VertxGreeterGrpcClient.SayHello)
.compose(request -> {
System.out.println("Sending a request that should timeout due to the server deadline");
request.end(HelloRequest.newBuilder().setName("Julien").build());
return request.response().compose(GrpcReadStream::last);
})
.map(HelloReply::getMessage)
.recover(err -> {
System.out.println("Timeout as expected");
return Future.succeededFuture("Expected timeout");
});
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package io.vertx.example.grpc.deadline;

import io.grpc.examples.helloworld.HelloReply;
import io.grpc.examples.helloworld.HelloRequest;
import io.grpc.examples.helloworld.VertxGreeterGrpcClient;
import io.vertx.core.Future;
import io.vertx.core.VerticleBase;
import io.vertx.core.net.SocketAddress;
import io.vertx.grpc.client.GrpcClient;
import io.vertx.grpc.client.GrpcClientOptions;
import io.vertx.grpc.common.GrpcErrorException;
import io.vertx.grpc.common.GrpcStatus;
import io.vertx.launcher.application.VertxApplication;

import java.util.concurrent.TimeUnit;

/**
* @author <a href="mailto:[email protected]">Julien Viet</a>
*/
public class ClientWithStub extends VerticleBase {

public static void main(String[] args) {
VertxApplication.main(new String[]{ClientWithStub.class.getName()});
}

private GrpcClient client;

@Override
public Future<?> start() {
client = GrpcClient.client(vertx, new GrpcClientOptions()
.setTimeout(5)
.setTimeoutUnit(TimeUnit.SECONDS));
VertxGreeterGrpcClient stub = new VertxGreeterGrpcClient(client, SocketAddress.inetSocketAddress(8080, "localhost"));
HelloRequest request = HelloRequest.newBuilder().setName("Julien").build();
System.out.println("Sending a request that should timeout due to the server deadline");
return stub
.sayHello(request)
.map(HelloReply::getMessage)
.recover(err -> {
System.out.println("Timeout as expected");
return Future.succeededFuture("Expected timeout");
});
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package io.vertx.example.grpc.deadline;

import io.grpc.examples.helloworld.VertxGreeterGrpcServer;
import io.vertx.core.Future;
import io.vertx.core.Timer;
import io.vertx.core.VerticleBase;
import io.vertx.grpc.server.GrpcServer;
import io.vertx.grpc.server.GrpcServerOptions;
import io.vertx.launcher.application.VertxApplication;

/**
* @author <a href="mailto:[email protected]">Julien Viet</a>
*/
public class Server extends VerticleBase {

public static void main(String[] args) {
VertxApplication.main(new String[]{Server.class.getName()});
System.out.println("Server started");
}

@Override
public Future<?> start() {
// Create the server
GrpcServer rpcServer = GrpcServer.server(vertx, new GrpcServerOptions()
.setScheduleDeadlineAutomatically(true));

// The rpc service
rpcServer.callHandler(VertxGreeterGrpcServer.SayHello, request -> {
Timer deadline = request.deadline();
if (deadline != null) {
System.out.println("This request has a deadline");
deadline.onSuccess(v -> {
System.out.println("Deadline fired");
});
}
request
.last()
.onSuccess(msg -> {
// Do not send a response to trigger timeout
});
});

// start the server
return vertx
.createHttpServer()
.requestHandler(rpcServer)
.listen(8080);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package io.vertx.example.grpc.deadline;

import io.grpc.examples.helloworld.HelloReply;
import io.grpc.examples.helloworld.HelloRequest;
import io.grpc.examples.helloworld.VertxGreeterGrpcServer;
import io.vertx.core.Future;
import io.vertx.core.Promise;
import io.vertx.core.VerticleBase;
import io.vertx.grpc.server.GrpcServer;
import io.vertx.grpc.server.GrpcServerOptions;
import io.vertx.launcher.application.VertxApplication;

/**
* @author <a href="mailto:[email protected]">Julien Viet</a>
*/
public class ServerWithStub extends VerticleBase {

public static void main(String[] args) {
VertxApplication.main(new String[]{ServerWithStub.class.getName()});
System.out.println("Server started");
}

@Override
public Future<?> start() {
VertxGreeterGrpcServer.GreeterApi service = new VertxGreeterGrpcServer.GreeterApi() {
@Override
public Future<HelloReply> sayHello(HelloRequest request) {
// Do not send a response to trigger timeout
return Promise.<HelloReply>promise().future();
}
};

// Create the server
GrpcServer rpcServer = GrpcServer.server(vertx, new GrpcServerOptions().setScheduleDeadlineAutomatically(true));

// Bind the service
service.bind_sayHello(rpcServer);

// start the server
return vertx
.createHttpServer()
.requestHandler(rpcServer)
.listen(8080);
}
}

0 comments on commit 6490518

Please sign in to comment.