Are you required to call Recv until you get io.EOF when interacting with grpc.ClientStreams?

Issue

Suppose I define the following gRPC service:

service Library {
  rpc Search(SearchBookRequest) returns (stream SearchBookResponse) {} 
}

message SearchBookRequest {
  string term = 1;
  int32 max_results = 2;
}

message SearchBookResponse {
  int32 book_id = 1;
}

It streams search results back up to a specified maximum. When interacting with the service via gRPC’s Go API, am I allowed to do something like this?

for i:=0; i<maxResults; i++ {
  search_result, err := stream.Recv()
  if err == io.EOF {
    // Note: If `maxResults` are returned this will never be reached.
    break
  }
  if err != nil {
    log.Fatalf("search error: %v", err)
  }
  fmt.Printf("Book-ID: %d\n", search_result.BookId)
}

Or am I required to keep calling Recv until I get io.EOF to ensure that gRPC properly cleans up all its resources?

Solution

Your code is correct.

You can exit on errors. You don’t need to wait for an EOF.


Edit: the answer above is incomplete.

The caller should keep receiving until an error, otherwise there could be leaks. There are other ways to avoid leaks, like canceling the context. See https://pkg.go.dev/google.golang.org/grpc#ClientConn.NewStream for details.

Answered By – menghanl

Answer Checked By – Mildred Charles (GoLangFix Admin)

Leave a Reply

Your email address will not be published.