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

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 1:[1]

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.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1