Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Document how to have a server close a bidirectional streaming call #518

Open
CodingCanuck opened this issue Aug 3, 2022 · 0 comments
Open

Comments

@CodingCanuck
Copy link
Contributor

I'm trying to write a streaming call that's terminated by the server, where the client doesn't call call.Finish() and thus the server doesn't wait for anything from the client.

This should be a valid mode of gRPC operation: https://grpc.io/docs/what-is-grpc/core-concepts/#rpc-termination

It’s also possible for a server to decide to complete before a client has sent all its requests.

I currently don't know how to do this, because bidirectional streaming RPC server handlers end with a call to StreamingEpilogue():

return TypeErased{{ method.name }}(&args)
>> StreamingEpilogue(call);
which ends by running call.WaitForDone():
[[nodiscard]] auto StreamingEpilogue(ServerCall<Request, Response>& call) {
return Map([&](auto&& response) {
return call.Writer().Write(response);
})
>> Loop()
>> Just(::grpc::Status::OK)
>> Catch()
.raised<std::exception>([](std::exception&& e) {
return ::grpc::Status(::grpc::UNKNOWN, e.what());
})
>> Then([&](::grpc::Status status) {
return call.Finish(status)
>> Finally([&](expected<void, std::exception_ptr>&& e) {
return If(e.has_value())
.no([e = std::move(e), &call]() {
return Raise(std::move(e.error()))
>> Catch()
.raised<std::exception>(
[&call](std::exception&& e) {
EVENTUALS_GRPC_LOG(1)
<< "Finishing call ("
<< call.context() << ")"
<< " for host = "
<< call.context()->host()
<< " and path = "
<< call.context()
->method()
<< " failed: "
<< e.what();
});
})
.yes([]() { return Just(); })
>> call.WaitForDone();

I don't think the server should be required to wait for the client to mark a call as done per the above quote about a server deciding to complete a call with no input from the client.

Glancing through the examples in

>> StreamingEpilogue(call);
, I don't see any tests in which the client does not call call.Finish().

The use case I'm thinking of is an infinite duration streaming RPC where the client connects to the server indefinitely, until the server decides to stop the call (e.g. in a unit test, where the server would like to finish the call to conclude the test).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant