1 /* 2 * Copyright 2023 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.debug; 18 19 import io.grpc.Channel; 20 import io.grpc.Grpc; 21 import io.grpc.InsecureChannelCredentials; 22 import io.grpc.InsecureServerCredentials; 23 import io.grpc.ManagedChannel; 24 import io.grpc.Server; 25 import io.grpc.ServerBuilder; 26 import io.grpc.StatusRuntimeException; 27 import io.grpc.examples.helloworld.GreeterGrpc; 28 import io.grpc.examples.helloworld.HelloReply; 29 import io.grpc.examples.helloworld.HelloRequest; 30 import io.grpc.protobuf.services.ProtoReflectionService; 31 import io.grpc.services.AdminInterface; 32 import java.util.concurrent.TimeUnit; 33 import java.util.logging.Level; 34 import java.util.logging.Logger; 35 36 /** 37 * A client that creates a channelz service and then requests a greeting 50 times. 38 * It uses 2 channels to communicate with the server one of which is shared by 2 stubs and 39 * one of which has only 1 stub. The requests are split over the 3 channels. 40 * Once completed, there is a 30 second sleep to allow more time to run the commandline debugger. 41 */ 42 public class HelloWorldDebuggableClient { 43 44 private static final Logger logger = Logger.getLogger(HelloWorldDebuggableClient.class.getName()); 45 public static final int NUM_ITERATIONS = 50; 46 47 private final GreeterGrpc.GreeterBlockingStub blockingStub; 48 49 /** Construct client for accessing HelloWorld server using the specified channel. */ HelloWorldDebuggableClient(Channel channel)50 public HelloWorldDebuggableClient(Channel channel) { 51 blockingStub = GreeterGrpc.newBlockingStub(channel); 52 } 53 54 /** Say hello to server. */ greet(String name)55 public void greet(String name) { 56 logger.info("Will try to greet " + name + " ..."); 57 HelloRequest request = HelloRequest.newBuilder().setName(name).build(); 58 HelloReply response; 59 try { 60 response = blockingStub.sayHello(request); 61 } catch (StatusRuntimeException e) { 62 logger.log(Level.WARNING, "RPC failed: {0}", e.getStatus()); 63 return; 64 } 65 logger.info("Greeting: " + response.getMessage()); 66 } 67 68 /** 69 * Greet server. If provided, the first element of {@code args} is the name to use in the 70 * greeting. The second argument is the target server. 71 */ main(String[] args)72 public static void main(String[] args) throws Exception { 73 String user = "world"; 74 // Access a service running on the local machine on port 50051 75 String target = "localhost:50051"; 76 int debugPort = 51051; 77 // Allow passing in the user and target strings as command line arguments 78 if (args.length > 0) { 79 if ("--help".equals(args[0])) { 80 System.err.println("Usage: [name [target]]"); 81 System.err.println(""); 82 System.err.println(" name The name you wish to be greeted by. Defaults to " + user); 83 System.err.println(" target The server to connect to. Defaults to " + target); 84 System.exit(1); 85 } 86 user = args[0]; 87 } 88 if (args.length > 1) { 89 target = args[1]; 90 } 91 92 // Create a pair of communication channels to the server. Channels are thread-safe 93 // and reusable. 94 ManagedChannel channel1 = Grpc.newChannelBuilder(target, 95 InsecureChannelCredentials.create()).build(); 96 ManagedChannel channel2 = Grpc.newChannelBuilder(target, 97 InsecureChannelCredentials.create()).build(); 98 Server server = null; 99 try { 100 // Create a service from which grpcdebug can request debug info 101 server = Grpc.newServerBuilderForPort(debugPort, InsecureServerCredentials.create()) 102 .addServices(AdminInterface.getStandardServices()) 103 .build() 104 .start(); 105 106 // Create the 3 clients 107 HelloWorldDebuggableClient client1 = new HelloWorldDebuggableClient(channel1); 108 HelloWorldDebuggableClient client2 = new HelloWorldDebuggableClient(channel1); 109 HelloWorldDebuggableClient client3 = new HelloWorldDebuggableClient(channel2); 110 111 // Do the client requests spreadying them over the 3 clients 112 for (int i=0; i < NUM_ITERATIONS; i++) { 113 switch (i % 3) { 114 case 0: 115 client1.greet(user); 116 break; 117 case 1: 118 client2.greet(user); 119 break; 120 case 2: 121 client3.greet(user); 122 break; 123 } 124 } 125 System.out.println("Completed " + NUM_ITERATIONS + 126 " requests, will now sleep for 30 seconds to give some time for command line calls"); 127 Thread.sleep(30000); // Give some time for running grpcdebug 128 } finally { 129 // ManagedChannels use resources like threads and TCP connections. To prevent leaking these 130 // resources the channel should be shut down when it will no longer be used. If it may be used 131 // again leave it running. 132 channel1.shutdownNow().awaitTermination(5, TimeUnit.SECONDS); 133 channel2.shutdownNow().awaitTermination(5, TimeUnit.SECONDS); 134 135 if (server != null) { 136 server.shutdownNow().awaitTermination(5, TimeUnit.SECONDS); 137 } 138 } 139 } 140 } 141