mirror of https://github.com/grpc/grpc-java.git
examples: waitForReady example (#9960)
Add an example using waitForReady Part of fixit. Fixes b/259286751
This commit is contained in:
parent
dba3c04608
commit
18a318c6c8
|
|
@ -23,6 +23,8 @@ before trying out the examples.
|
|||
|
||||
- [Flow control](src/main/java/io/grpc/examples/manualflowcontrol)
|
||||
|
||||
- [Wait For Ready](src/main/java/io/grpc/examples/waitforready)
|
||||
|
||||
- [Json serialization](src/main/java/io/grpc/examples/advanced)
|
||||
|
||||
- <details>
|
||||
|
|
|
|||
|
|
@ -139,6 +139,13 @@ task manualFlowControlServer(type: CreateStartScripts) {
|
|||
classpath = startScripts.classpath
|
||||
}
|
||||
|
||||
task waitForReadyClient(type: CreateStartScripts) {
|
||||
mainClass = 'io.grpc.examples.waitforready.WaitForReadyClient'
|
||||
applicationName = 'wait-for-ready-client'
|
||||
outputDir = new File(project.buildDir, 'tmp/scripts/' + name)
|
||||
classpath = startScripts.classpath
|
||||
}
|
||||
|
||||
task loadBalanceServer(type: CreateStartScripts) {
|
||||
mainClass = 'io.grpc.examples.loadbalance.LoadBalanceServer'
|
||||
applicationName = 'load-balance-server'
|
||||
|
|
@ -207,6 +214,7 @@ applicationDistribution.into('bin') {
|
|||
from(compressingHelloWorldClient)
|
||||
from(manualFlowControlClient)
|
||||
from(manualFlowControlServer)
|
||||
from(waitForReadyClient)
|
||||
from(loadBalanceServer)
|
||||
from(loadBalanceClient)
|
||||
from(nameResolveServer)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,132 @@
|
|||
/*
|
||||
* Copyright 2023 The gRPC Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.grpc.examples.waitforready;
|
||||
|
||||
import io.grpc.Channel;
|
||||
import io.grpc.Deadline;
|
||||
import io.grpc.Grpc;
|
||||
import io.grpc.InsecureChannelCredentials;
|
||||
import io.grpc.ManagedChannel;
|
||||
import io.grpc.StatusRuntimeException;
|
||||
import io.grpc.examples.helloworld.GreeterGrpc;
|
||||
import io.grpc.examples.helloworld.HelloRequest;
|
||||
import io.grpc.examples.helloworld.HelloReply;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* This is an example of using waitForReady. This is a feature which can be used on a stub
|
||||
* which will cause the rpcs to wait (until optional deadline is exceeded) for the
|
||||
* server to become available before sending the request. This is useful for batch workflows
|
||||
* where there is no need to fail fast.
|
||||
*
|
||||
* Below is a simple client that requests a greeting from the
|
||||
* {@link io.grpc.examples.helloworld.HelloWorldServer} and defines waitForReady on the stub.
|
||||
* To test,
|
||||
* 1. run this client without a server running - client rpc should hang
|
||||
* 2. start the server - client rpc should complete
|
||||
* 3. run this client again - client rpc should complete nearly immediately
|
||||
*/
|
||||
public class WaitForReadyClient {
|
||||
private static final Logger logger = Logger.getLogger(WaitForReadyClient.class.getName());
|
||||
|
||||
private final GreeterGrpc.GreeterBlockingStub blockingStub;
|
||||
|
||||
/**
|
||||
* Construct client for accessing HelloWorld server using the existing channel which will
|
||||
* wait for the server to become ready, however long that may take, before sending the request.
|
||||
*/
|
||||
public WaitForReadyClient(Channel channel) {
|
||||
// This is the only difference from the simple HelloWorld example
|
||||
blockingStub = GreeterGrpc.newBlockingStub(channel).withWaitForReady();
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a client for accessing HelloWorld server using the existing channel which will
|
||||
* wait for the server to become ready, up to the specified deadline, before sending the request.
|
||||
* if the deadline is exceeded before the server becomes ready, then the rpc call will fail with
|
||||
* a Status of DEADLINE_EXCEEDED without the request being sent.
|
||||
*/
|
||||
public WaitForReadyClient(Channel channel, Deadline deadline) {
|
||||
blockingStub = GreeterGrpc.newBlockingStub(channel).withWaitForReady().withDeadline(deadline);
|
||||
}
|
||||
|
||||
|
||||
/** Say hello to server. */
|
||||
public void greet(String name) {
|
||||
logger.info("Will try to greet " + name + " ...");
|
||||
HelloRequest request = HelloRequest.newBuilder().setName(name).build();
|
||||
HelloReply response;
|
||||
try {
|
||||
response = blockingStub.sayHello(request);
|
||||
} catch (StatusRuntimeException e) {
|
||||
logger.log(Level.WARNING, "RPC failed: {0}", e.getStatus());
|
||||
return;
|
||||
}
|
||||
logger.info("Greeting: " + response.getMessage());
|
||||
}
|
||||
|
||||
/**
|
||||
* Greet server. If provided, the first element of {@code args} is the name to use in the
|
||||
* greeting. The second argument is the target server.
|
||||
*/
|
||||
public static void main(String[] args) throws Exception {
|
||||
String user = "world";
|
||||
// Access a service running on the local machine on port 50051
|
||||
String target = "localhost:50051";
|
||||
// Allow passing in the user and target strings as command line arguments
|
||||
if (args.length > 0) {
|
||||
if ("--help".equals(args[0])) {
|
||||
System.err.println("Usage: [name [target]]");
|
||||
System.err.println();
|
||||
System.err.println(" name The name you wish to be greeted by. Defaults to " + user);
|
||||
System.err.println(" target The server to connect to. Defaults to " + target);
|
||||
System.exit(1);
|
||||
}
|
||||
user = args[0];
|
||||
}
|
||||
if (args.length > 1) {
|
||||
target = args[1];
|
||||
}
|
||||
|
||||
// Create a communication channel to the server, known as a Channel. Channels are thread-safe
|
||||
// and reusable. It is common to create channels at the beginning of your application and reuse
|
||||
// them until the application shuts down.
|
||||
//
|
||||
// For the example we use plaintext insecure credentials to avoid needing TLS certificates. To
|
||||
// use TLS, use TlsChannelCredentials instead.
|
||||
ManagedChannel channel = Grpc.newChannelBuilder(target, InsecureChannelCredentials.create())
|
||||
.build();
|
||||
try {
|
||||
// If server isn't running, this will fail after 5 seconds. Will also fail if the server is
|
||||
// running particularly slowly and takes more than 5 minutes to respond.
|
||||
WaitForReadyClient clientWithTimeout =
|
||||
new WaitForReadyClient(channel, Deadline.after(5, TimeUnit.SECONDS));
|
||||
clientWithTimeout.greet(user);
|
||||
|
||||
// This will wait forever until the server becomes ready
|
||||
WaitForReadyClient client = new WaitForReadyClient(channel);
|
||||
client.greet(user);
|
||||
} finally {
|
||||
// ManagedChannels use resources like threads and TCP connections. To prevent leaking these
|
||||
// resources the channel should be shut down when it will no longer be used. If it may be used
|
||||
// again leave it running.
|
||||
channel.shutdownNow().awaitTermination(5, TimeUnit.SECONDS);
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue