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 java.text.DecimalFormat; 20 import java.util.Random; 21 import java.util.concurrent.atomic.AtomicInteger; 22 import io.grpc.Grpc; 23 import io.grpc.InsecureServerCredentials; 24 import io.grpc.Server; 25 import io.grpc.Status; 26 import io.grpc.examples.helloworld.GreeterGrpc; 27 import io.grpc.examples.helloworld.HelloReply; 28 import io.grpc.examples.helloworld.HelloRequest; 29 import io.grpc.stub.StreamObserver; 30 import java.io.IOException; 31 import java.util.concurrent.TimeUnit; 32 import java.util.logging.Logger; 33 34 /** 35 * A HelloWorld server that responds to requests with UNAVAILABLE with a given percentage. 36 */ 37 public class RetryingHelloWorldServer { 38 private static final Logger logger = Logger.getLogger(RetryingHelloWorldServer.class.getName()); 39 private static final float UNAVAILABLE_PERCENTAGE = 0.5F; 40 private static final Random random = new Random(); 41 42 private Server server; 43 start()44 private void start() throws IOException { 45 /* The port on which the server should run */ 46 int port = 50051; 47 server = Grpc.newServerBuilderForPort(port, InsecureServerCredentials.create()) 48 .addService(new GreeterImpl()) 49 .build() 50 .start(); 51 logger.info("Server started, listening on " + port); 52 53 DecimalFormat df = new DecimalFormat("#%"); 54 logger.info("Responding as UNAVAILABLE to " + df.format(UNAVAILABLE_PERCENTAGE) + " requests"); 55 Runtime.getRuntime().addShutdownHook(new Thread() { 56 @Override 57 public void run() { 58 // Use stderr here since the logger may have been reset by its JVM shutdown hook. 59 System.err.println("*** shutting down gRPC server since JVM is shutting down"); 60 try { 61 RetryingHelloWorldServer.this.stop(); 62 } catch (InterruptedException e) { 63 e.printStackTrace(System.err); 64 } 65 System.err.println("*** server shut down"); 66 } 67 }); 68 } 69 stop()70 private void stop() throws InterruptedException { 71 if (server != null) { 72 server.shutdown().awaitTermination(30, TimeUnit.SECONDS); 73 } 74 } 75 76 /** 77 * Await termination on the main thread since the grpc library uses daemon threads. 78 */ blockUntilShutdown()79 private void blockUntilShutdown() throws InterruptedException { 80 if (server != null) { 81 server.awaitTermination(); 82 } 83 } 84 85 /** 86 * Main launches the server from the command line. 87 */ main(String[] args)88 public static void main(String[] args) throws IOException, InterruptedException { 89 final RetryingHelloWorldServer server = new RetryingHelloWorldServer(); 90 server.start(); 91 server.blockUntilShutdown(); 92 } 93 94 static class GreeterImpl extends GreeterGrpc.GreeterImplBase { 95 AtomicInteger retryCounter = new AtomicInteger(0); 96 97 @Override sayHello(HelloRequest request, StreamObserver<HelloReply> responseObserver)98 public void sayHello(HelloRequest request, StreamObserver<HelloReply> responseObserver) { 99 int count = retryCounter.incrementAndGet(); 100 if (random.nextFloat() < UNAVAILABLE_PERCENTAGE) { 101 logger.info("Returning stubbed UNAVAILABLE error. count: " + count); 102 responseObserver.onError(Status.UNAVAILABLE 103 .withDescription("Greeter temporarily unavailable...").asRuntimeException()); 104 } else { 105 logger.info("Returning successful Hello response, count: " + count); 106 HelloReply reply = HelloReply.newBuilder().setMessage("Hello " + request.getName()).build(); 107 responseObserver.onNext(reply); 108 responseObserver.onCompleted(); 109 } 110 } 111 } 112 } 113