0

I am exploring on grpc

My sample application fetches few records from Database + reads a file from S3(very small file) and returns the combined result.

Since the file size is very less, i am not using streams.

So, the service layer of my application will return a CompletableFuture

 CompletableFuture<Book> getContent(String bookId);

My Grpc ServiceBaseImpl will have the below code.

  public void getBook(GetBookrequest request, StreamObserver<Book> responseObserver){
    CompletableFuture<Book> bookContentFuture = bookService.getContent(request.getBookId());
    Book book = bookContentFuture.get() ; // blocking 
    responseObserver.onNext(book);
    responseObserver.onCompleted();
}

Here i am making a blocking get call and waiting for the result before send the response back.

In Rest Application , i can have a controller which can return the CompletableFuture<Book>

Is it possible to return a Future in GRPC . I don`t find any future type in protobuf , it means its okay to block before responding?

Jeevi
  • 2,962
  • 6
  • 39
  • 60
  • I don’t understand the problem here. If you want to return a future/promise type object from your method, you can do so using whatever create method that object provides. Within the create method, you’ll write your DB code, but until the promise is fulfilled at a later time, this call won’t be executed. This seems to be completely unrelated with Protobuf. – Abhijit Sarkar Jul 14 '23 at 22:20

2 Answers2

0

generally not recommended to block and wait for CompletableFuture .

if you have a small file size and dont want to use streaming, you can theoretically blcok and wait for CompletableFuture before sending the response back.

you can still return CompletableFuture from the service method.

something like this

import io.grpc.stub.StreamObserver;
import io.grpc.Status;
import io.grpc.StatusRuntimeException;
import com.google.common.util.concurrent.MoreExecutors;
import io.grpc.stub.ServerCallStreamObserver;

public void getBook(GetBookRequest request, StreamObserver<Book> responseObserver) {
  CompletableFuture<Book> bookContentFuture = bookService.getContent(request.getBookId());

  bookContentFuture.whenCompleteAsync((book, throwable) -> {
    if (throwable != null) {
      StatusRuntimeException exception = Status.INTERNAL
          .withDescription("Error retrieving book content")
          .withCause(throwable)
          .asRuntimeException();
      responseObserver.onError(exception);
    } else {
      responseObserver.onNext(book);
      responseObserver.onCompleted();
    }
  }, MoreExecutors.directExecutor());
}
Alex Gordon
  • 57,446
  • 287
  • 670
  • 1,062
0

It sounds like you're just looking for the future stub or asynchronous stub.

Louis Wasserman
  • 191,574
  • 25
  • 345
  • 413