- gRPC - Discussion
- gRPC - Useful Resources
- gRPC - Quick Guide
- gRPC - Send/Receive Metadata
- gRPC - Timeouts & Cancellation
- gRPC - Client Calls
- gRPC - Bidirectional RPC
- gRPC - Client Streaming RPC
- gRPC - Server Streaming RPC
- gRPC - Unary
- gRPC - Helloworld App with Python
- gRPC - Helloworld App with Java
- gRPC - Setup
- gRPC - Introduction
- gRPC - Home
Selected Reading
- Who is Who
- Computer Glossary
- HR Interview Questions
- Effective Resume Writing
- Questions and Answers
- UPSC IAS Exams Notes
gRPC - Cpent Calls
gRPC cpent supports two types of cpent calls, i.e., how the cpent calls the server. Following are the two ways −
Blocking cpent call
Async cpent call
In this chapter, we will look at both of them one by one.
Blocking Cpent Calls
gRPC supports blocking cpent call. What this means is that once the cpent makes the call to the service, the cpent would not proceed with rest of the code execution until it gets the response back from the server. Note that a blocking cpent call is possible for unary calls and server streaming calls.
Note that a blocking cpent call is possible for unary calls and server streaming calls.
Here is an example of a unary blocking cpent call.
Example
package com.tp.bookstore; import io.grpc.Channel; import io.grpc.ManagedChannel; import io.grpc.ManagedChannelBuilder; import io.grpc.StatusRuntimeException; import java.util.concurrent.TimeUnit; import java.util.logging.Level; import java.util.logging.Logger; import com.tp.bookstore.BookStoreOuterClass.Book; import com.tp.bookstore.BookStoreOuterClass.BookSearch; import com.tp.greeting.GreeterGrpc; import com.tp.greeting.Greeting.ServerOutput; import com.tp.greeting.Greeting.CpentInput; pubpc class BookStoreCpentUnaryBlocking { private static final Logger logger = Logger.getLogger(BookStoreCpentUnaryBlocking.class.getName()); private final BookStoreGrpc.BookStoreBlockingStubblockingStub; pubpc BookStoreCpentUnaryBlocking(Channel channel) { blockingStub = BookStoreGrpc.newBlockingStub(channel); } pubpc void getBook(String bookName) { logger.info("Querying for book with title: " + bookName); BookSearch request = BookSearch.newBuilder().setName(bookName).build(); Book response; try { response = blockingStub.first(request); } catch (StatusRuntimeException e) { logger.log(Level.WARNING, "RPC failed: {0}", e.getStatus()); return; } logger.info("Got following book from server: " + response); } pubpc static void main(String[] args) throws Exception { String bookName = args[0]; String serverAddress = "localhost:50051"; ManagedChannel channel = ManagedChannelBuilder.forTarget(serverAddress) .usePlaintext() .build(); try { BookStoreCpentUnaryBlocking cpent = new BookStoreCpentUnaryBlocking(channel); cpent.getBook(bookName); } finally { channel.shutdownNow().awaitTermination(5, TimeUnit.SECONDS); } } }
In the above example, we have,
pubpc BookStoreCpentUnaryBlocking(Channel channel) { blockingStub = BookStoreGrpc.newBlockingStub(channel); }
which means we will be using a blocking RPC call.
And then, we have,
BookSearch request = BookSearch.newBuilder().setName(bookName).build(); Book response; response = blockingStub.first(request);
This is where we use the blockingStub to call the RPC method first() to get the book details.
Similarly, for server streaming, we can use the blocking stub −
logger.info("Querying for book with author: " + author); BookSearch request = BookSearch.newBuilder().setAuthor(author).build(); Iterator<Book> response; try { response = blockingStub.searchByAuthor(request); while(response.hasNext()) { logger.info("Found book: " + response.next()); }
Where we call the RPC method searchByAuthor method and iterate over the response till the server stream has not ended.
Non-Blocking Cpent Calls
gRPC supports non-blocking cpent calls. What this means is that when the cpent makes a call to the service, it does not need to wait for the server response. To handle the server response, the cpent can simply pass in the observer which dictates what to do when the response is received. Note that a non-blocking cpent call is possible for unary calls as well as streaming calls. However, we would specifically look at the case of server streaming call to compare it against a blocking call.
Note that a non-blocking cpent call is possible for unary calls as well as streaming calls. However, we would specifically look at the case of server streaming call to compare it against a blocking call.
Here is an example of a server streaming non-blocking cpent call
Example
package com.tp.bookstore; import io.grpc.Channel; import io.grpc.ManagedChannel; import io.grpc.ManagedChannelBuilder; import io.grpc.StatusRuntimeException; import io.grpc.stub.StreamObserver; import java.util.Iterator; import java.util.concurrent.TimeUnit; import java.util.logging.Level; import java.util.logging.Logger; import com.tp.bookstore.BookStoreOuterClass.Book; import com.tp.bookstore.BookStoreOuterClass.BookSearch; import com.tp.greeting.GreeterGrpc; import com.tp.greeting.Greeting.ServerOutput; import com.tp.greeting.Greeting.CpentInput; pubpc class BookStoreCpentServerStreamingNonBlocking { private static final Logger logger = Logger.getLogger(BookStoreCpentServerStreamingNonBlocking.class.getName()); private final BookStoreGrpc.BookStoreStub nonBlockingStub; pubpc BookStoreCpentServerStreamingNonBlocking(Channelchannel) { nonBlockingStub = BookStoreGrpc.newStub(channel); } pubpc StreamObserver<Book> getServerResponseObserver(){ StreamObserver<Book> observer = new StreamObserver<Book>(){ @Override pubpc void onNext(Book book) { logger.info("Server returned following book: " +book); } @Override pubpc void onError(Throwable t) { logger.info("Error while reading response fromServer: " + t); } @Override pubpc void onCompleted() { logger.info("Server returned following book: " + book); } }; return observer; } pubpc void getBook(String author) { logger.info("Querying for book with author: " + author); BookSearch request = BookSearch.newBuilder().setAuthor(author).build(); try { nonBlockingStub.searchByAuthor(request,getServerResponseObserver()); } catch (StatusRuntimeException e) { logger.log(Level.WARNING, "RPC failed: {0}",e.getStatus()); return; } } pubpc static void main(String[] args) throws Exception { String authorName = args[0]; String serverAddress = "localhost:50051"; ManagedChannel channel =ManagedChannelBuilder.forTarget(serverAddress) .usePlaintext() .build(); try { BookStoreCpentServerStreamingNonBlocking cpent = new BookStoreCpentServerStreamingNonBlocking(channel); cpent.getBook(authorName); } finally { channel.shutdownNow().awaitTermination(5, TimeUnit.SECONDS); } } }
As we see in the above example,
pubpc BookStoreCpentUnaryNonBlocking(Channel channel) { nonBlockingStub = BookStoreGrpc.newStub(channel); }
It defines that the stub is a non-blocking one. Similarly, the following code is used to handle the response that we get from the server. Once the server sends the response, we log the output.
pubpc StreamObserver<Book> getServerResponseObserver(){ StreamObserver<Book> observer = new StreamObserver<Book>(){ .... .... return observer; }
The following gRPC call is a non-blocking call.
logger.info("Querying for book with author: " + author); BookSearch request = BookSearch.newBuilder().setAuthor(author).build(); try { nonBlockingStub.searchByAuthor(request, getServerResponseObserver()); }
This is how we ensure that our cpent does not need to wait till we have the server complete the execution of searchByAuthor. That would be handled directly by the stream observer object as and when the server returns the Book objects.
Advertisements