title: Is it safe to interact with StreamObserver asynchronously, i.e. with Java 8+ CompletableFutures?
body: <p>I'm looking at the <a href="https://grpc.io/docs/tutorials/basic/java/#server" rel="nofollow noreferrer">Simple RPC example from grpc.io's basic tutorial</a>:</p>
  
  <pre><code>@Override
  public void getFeature(Point request, StreamObserver&lt;Feature&gt; responseObserver) {
    responseObserver.onNext(checkFeature(request));
    responseObserver.onCompleted();
  }
  
  ...
  
  private Feature checkFeature(Point location) {
    for (Feature feature : features) {
      if (feature.getLocation().getLatitude() == location.getLatitude()
          &amp;&amp; feature.getLocation().getLongitude() == location.getLongitude()) {
        return feature;
      }
    }
  
    // No feature was found, return an unnamed feature.
    return Feature.newBuilder().setName("").setLocation(location).build();
  }
  </code></pre>
  
  <p><strong>Are there any caveats to interacting with the StreamObserver from other threads?</strong> For example, say <code>checkFeature()</code> asynchronously hits another service, returning a CompletableFuture:</p>
  
  <pre><code>@Override
  public void getFeature(Point request, StreamObserver&lt;Feature&gt; responseObserver) {
    checkFeature(request).
        thenAccept(feature -&gt; responseObserver.onNext(feature));
    responseObserver.onCompleted();
  }
  </code></pre>
  
  <p>Of course the above wouldn't work because the first thread would execute <code>onCompleted()</code> before the feature is returned. So let's fix that:</p>
  
  <pre><code>@Override
  public void getFeature(Point request, StreamObserver&lt;Feature&gt; responseObserver) {
    checkFeature(request).
        thenAccept(feature -&gt; {
          responseObserver.onNext(feature);
          responseObserver.onCompleted();
        });
  }
  </code></pre>
  
  <p>I think this should work, but I'm new to Java so I wonder what ramifications there are. For example,</p>
  
  <ul>
  <li>Will <code>Context.current()</code> be consistent?</li>
  <li>Will anything cause the StreamObserver to destruct or close prematurely besides <code>onNext()</code> for a unary calls and <code>onError()</code>?</li>
  <li>Is there a better practice?</li>
  </ul>
  
  <p>It would be great if someone could also step me through how they reasoned. I tried looking up actual implementations of <code>StreamObserver</code> but I wasn't sure what to look for.</p>