1 /* 2 * Copyright 2020 The gRPC Authors 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package io.grpc.examples.retrying; 18 19 import static java.nio.charset.StandardCharsets.UTF_8; 20 21 import com.google.gson.Gson; 22 import com.google.gson.stream.JsonReader; 23 import io.grpc.Grpc; 24 import io.grpc.InsecureChannelCredentials; 25 import io.grpc.ManagedChannel; 26 import io.grpc.ManagedChannelBuilder; 27 import io.grpc.StatusRuntimeException; 28 import io.grpc.examples.helloworld.GreeterGrpc; 29 import io.grpc.examples.helloworld.HelloReply; 30 import io.grpc.examples.helloworld.HelloRequest; 31 import java.io.InputStreamReader; 32 import java.util.Map; 33 import java.util.concurrent.ForkJoinPool; 34 import java.util.concurrent.TimeUnit; 35 import java.util.concurrent.atomic.AtomicInteger; 36 import java.util.logging.Level; 37 import java.util.logging.Logger; 38 39 /** 40 * A client that requests a greeting from the {@link RetryingHelloWorldServer} with a retrying policy. 41 */ 42 public class RetryingHelloWorldClient { 43 static final String ENV_DISABLE_RETRYING = "DISABLE_RETRYING_IN_RETRYING_EXAMPLE"; 44 45 private static final Logger logger = Logger.getLogger(RetryingHelloWorldClient.class.getName()); 46 47 private final boolean enableRetries; 48 private final ManagedChannel channel; 49 private final GreeterGrpc.GreeterBlockingStub blockingStub; 50 private final AtomicInteger totalRpcs = new AtomicInteger(); 51 private final AtomicInteger failedRpcs = new AtomicInteger(); 52 getRetryingServiceConfig()53 protected Map<String, ?> getRetryingServiceConfig() { 54 return new Gson() 55 .fromJson( 56 new JsonReader( 57 new InputStreamReader( 58 RetryingHelloWorldClient.class.getResourceAsStream( 59 "retrying_service_config.json"), 60 UTF_8)), 61 Map.class); 62 } 63 64 /** 65 * Construct client connecting to HelloWorld server at {@code host:port}. 66 */ RetryingHelloWorldClient(String host, int port, boolean enableRetries)67 public RetryingHelloWorldClient(String host, int port, boolean enableRetries) { 68 69 ManagedChannelBuilder<?> channelBuilder 70 = Grpc.newChannelBuilderForAddress(host, port, InsecureChannelCredentials.create()); 71 if (enableRetries) { 72 Map<String, ?> serviceConfig = getRetryingServiceConfig(); 73 logger.info("Client started with retrying configuration: " + serviceConfig); 74 channelBuilder.defaultServiceConfig(serviceConfig).enableRetry(); 75 } 76 channel = channelBuilder.build(); 77 blockingStub = GreeterGrpc.newBlockingStub(channel); 78 this.enableRetries = enableRetries; 79 } 80 shutdown()81 public void shutdown() throws InterruptedException { 82 channel.shutdown().awaitTermination(60, TimeUnit.SECONDS); 83 } 84 85 /** 86 * Say hello to server in a blocking unary call. 87 */ greet(String name)88 public void greet(String name) { 89 HelloRequest request = HelloRequest.newBuilder().setName(name).build(); 90 HelloReply response = null; 91 StatusRuntimeException statusRuntimeException = null; 92 try { 93 response = blockingStub.sayHello(request); 94 } catch (StatusRuntimeException e) { 95 failedRpcs.incrementAndGet(); 96 statusRuntimeException = e; 97 } 98 99 totalRpcs.incrementAndGet(); 100 101 if (statusRuntimeException == null) { 102 logger.log(Level.INFO,"Greeting: {0}", new Object[]{response.getMessage()}); 103 } else { 104 logger.log(Level.INFO,"RPC failed: {0}", new Object[]{statusRuntimeException.getStatus()}); 105 } 106 } 107 printSummary()108 private void printSummary() { 109 logger.log( 110 Level.INFO, 111 "\n\nTotal RPCs sent: {0}. Total RPCs failed: {1}\n", 112 new Object[]{ 113 totalRpcs.get(), failedRpcs.get()}); 114 115 if (enableRetries) { 116 logger.log( 117 Level.INFO, 118 "Retrying enabled. To disable retries, run the client with environment variable {0}=true.", 119 ENV_DISABLE_RETRYING); 120 } else { 121 logger.log( 122 Level.INFO, 123 "Retrying disabled. To enable retries, unset environment variable {0} and then run the client.", 124 ENV_DISABLE_RETRYING); 125 } 126 } 127 main(String[] args)128 public static void main(String[] args) throws Exception { 129 boolean enableRetries = !Boolean.parseBoolean(System.getenv(ENV_DISABLE_RETRYING)); 130 final RetryingHelloWorldClient client = new RetryingHelloWorldClient("localhost", 50051, enableRetries); 131 ForkJoinPool executor = new ForkJoinPool(); 132 133 for (int i = 0; i < 50; i++) { 134 final String userId = "user" + i; 135 executor.execute( 136 new Runnable() { 137 @Override 138 public void run() { 139 client.greet(userId); 140 } 141 }); 142 } 143 executor.awaitQuiescence(100, TimeUnit.SECONDS); 144 executor.shutdown(); 145 client.printSummary(); 146 client.shutdown(); 147 } 148 } 149