title: What's the best way to determine when an RPC session ends using a StreamClientInterceptor?
body: <p>When writing a <a href="https://godoc.org/google.golang.org/grpc#StreamClientInterceptor" rel="nofollow noreferrer">StreamClientInterceptor</a> function, what's the best way to determine when an invoker finishes the RPC? This is straightforward enough with unary interceptors or on the server-side where you're passed a <a href="https://godoc.org/google.golang.org/grpc#StreamHandler" rel="nofollow noreferrer">handler</a> that performs the RPC, but it's not clear how best to do this on the client-side where you return a <a href="https://godoc.org/google.golang.org/grpc#ClientStream" rel="nofollow noreferrer">ClientStream</a> that the invoker then interacts with.</p>
  
  <p>One use case for this is instrumenting OpenTracing, where the goal is to start and finish a span to mark the beginning and end of the RPC.</p>
  
  <p>A strategy I'm looking into is having the stream interceptor return a decorated ClientStream. This new ClientStream considers the RPC to have completed if any of the interface methods <code>Header</code>, <code>CloseSend</code>, <code>SendMsg</code>, <code>RecvMsg</code> return an error or if the <code>Context</code> is cancelled. Additionally, it adds this logic to <code>RecvMsg</code>:</p>
  
  <pre><code>func (cs *DecoratedClientStream) RecvMsg(m interface{}) error {
      err := cs.ClientStream.RecvMsg(m)
      if err == io.EOF {
          // Consider the RPC as complete
          return err
      } else if err != nil {
          // Consider the RPC as complete
          return err
      }
      if !cs.isResponseStreaming {
          // Consider the RPC as complete
      }
      return err
  }
  </code></pre>
  
  <p>It would work in most cases, but my understanding is that an invoker isn't required to call <code>Recv</code> if it knows the result will be <code>io.EOF</code> (See <a href="https://stackoverflow.com/questions/42915337/are-you-required-to-call-recv-until-you-get-io-eof-when-interacting-with-grpc-cl/42939914#42939914">Are you required to call Recv until you get io.EOF when interacting with grpc.ClientStreams?</a>), so it wouldn't work in all cases. Is there a better way to accomplish this?</p>