Let me re-establish somethings just to make sure we are on the same page.
1. Servers are always async. Server Stubs are always passed a Response
observer. For Bidi and Client Streaming, they also return a Request
Observer.
2. Servers are usually on the receiving end of cancellation. Servers find
out about cancellation by inspecting the Context.current().isCancelled()
value.
3. Servers can also check for early termination of the RPC for Bidi and
ClientStreaming by getting onError() called on the Request observer.
4. Clients usually don't check for cancellation. Client's find out the
RPC is prematurely terminated by getting an onError() callback with a
StatusRuntimeException or StatusException with a status Code. From the
client's POV, server cancellation and regular failure look the same.
5. Clients using the blocking API usually use Context cancellation to end
the call early. (because there is no other way)
6. A blocking client will take the current context, wrap a cancellable
context around it, and install the new ctx back into the current. (This
was the attach() suggestion I made above). When the RPC is complete, they
swap the old context back into place.
7. ClientResponseObserver is probably not what you want here. It's meant
to modify flow control on the client stub. It's rarely used.
With these in mind, It seems like your server should just do
responseObserver.onError(Status.CANCELLED.withDescription("Server is
cancelling").asRuntimeException()); The client be notified by the
onError() invocation on it's response observer. (I think you said it's
bidi, so this would be the observer "returned" from your client stub.
Does this make sense?
On Thursday, February 21, 2019 at 11:20:54 AM UTC-8, [email protected]
wrote:
>
> Thanks for the reply. I updated my test server method to the following
> (hopefully I understood correctly), although I observed no differences in
> behavior on the client-side:
>
> public void testStream(TestRequest request, StreamObserver<TestResponse>
> responseObserver) {
> Context originalContext = Context.current();
> CancellableContext cancellableContext = originalContext.withCancellation();
> cancellableContext.attach();
> cancellableContext.detachAndCancel(originalContext, new
> RuntimeException("Server context canceled"));
> }
>
>
> It's the ClientResponseObserver that I'm inspecting to observe the
> cancellation, I suppose maybe expecting `onError` to get called on behalf
> of the server cancellation.
>
> On Thursday, February 21, 2019 at 1:50:23 PM UTC-5, Carl Mastrangelo wrote:
>>
>> I think you need to call `attach()` on the context to install it (rather
>> than just construct it). Normally this sticks it in a thread local which
>> gRPC then reads from.
>>
>> On Wednesday, February 20, 2019 at 2:08:03 PM UTC-8, [email protected]
>> wrote:
>>>
>>>
>>> In the context of server streaming or bi-directional streaming calls,
>>> I'm under the impression the client should be able to receive notice when
>>> the server has decided to cancel the context for the call. I've been trying
>>> to write up a test to capture this behavior, but it doesn't seem like
>>> canceling the context on the server is triggering anything in the response
>>> observer in the client side. Maybe I'm misinterpreting how the client
>>> interacts with a server cancellation or just setting up the test case wrong?
>>>
>>> My client test call is something like:
>>>
>>> ClientResponseObserver<Object, TestResponse> closingObserver =
>>> ClosingStreamObserver.closingClientResponseObserver(clientTestCloseable,
>>> responseObserver);
>>> serviceStub.testStream(req, closingObserver);
>>>
>>>
>>> and then I wait a bit to see if anything propagates (I've got an atomic
>>> boolean that I flip when `onError` or `onCompleted` get called. I had also
>>> tried a listener on the current context on the client side as well, but
>>> that seemed irrelevant.
>>>
>>>
>>> On the server side I'm canceling the context something like this:
>>>
>>> public void testStream(TestRequest request, StreamObserver<TestResponse>
>>> responseObserver) {
>>> CancellableContext cancellableContext =
>>> Context.current().withCancellation();
>>> cancellableContext.cancel(new RuntimeException("Server context
>>> canceled"));
>>> }
>>>
>>>
>>> To step back a bit, I'm looking to know if and how a server can signal it
>>> is canceling a request to the client.
>>>
>>>
--
You received this message because you are subscribed to the Google Groups
"grpc.io" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/grpc-io.
To view this discussion on the web visit
https://groups.google.com/d/msgid/grpc-io/3d6aa170-14a5-4c49-b3cb-0db48e79be2e%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.