Closed Marwin34 closed 6 days ago
Asio-grpc just acts as a small wrapper around gRPC's API. In the case of a client-streaming RPC, for example, that would be grpc::ServerAsyncWriter::Write. If that call really completes slowly for slow clients (I haven't tested it, also note this set_write_through option), then you can use it to automatically drop the connection like so:
const auto slow_threshold = std::chrono::seconds(5);
agrpc::Alarm alarm{grpc_context};
auto [completion_order, alarm_ok, write_ok] =
co_await asio::experimental::make_parallel_group(
alarm.wait(std::chrono::system_clock::now() + slow_threshold, asio::deferred),
rpc.write(response, asio::deferred))
.async_wait(asio::experimental::wait_for_one{}, asio::use_awaitable);
if (!write_ok)
{
// client dropped connection or was slow (alarm finished and caused cancellation of rpc with invokes grpc::ServerContext::TryCancel)
co_return;
}
How to call set_write_through
in asio-grpc ?
@nqf ServerRPC::write
, ServerRPC::write_and_finish
and ClientRPC::write
all take an optional second argument: grpc::WriteOptions. Which means you can do:
rpc.write(request, grpc::WriteOptions().set_write_through(), <completion token>);
rpc.write(request, grpc::WriteOptions().set_write_through(), <completion token>);
Is it possible for rpc.write
to throw an exception? As far as I know, ASIO can throw exceptions or return error codes
No, since gRPC never throws exceptions I am not inventing any either. The completion signature of rpc.write is void(bool)
which differs from the typical asio completion signatures void(error_code, <something>)
. Only if the first argument is an error_code
will asio automatically convert it to an exception.
From the asio-grpc documentation:
The completion signature is void(bool). true means that the data/metadata/status/etc is going to go to the wire. If it is false, it is not going to the wire because the call is already dead (i.e., canceled, deadline expired, other side dropped the channel, etc).
No, since gRPC never throws exceptions I am not inventing any either. The completion signature of rpc.write is
void(bool)
which differs from the typical asio completion signaturesvoid(error_code, <something>)
. Only if the first argument is anerror_code
will asio automatically convert it to an exception.From the asio-grpc documentation:
The completion signature is void(bool). true means that the data/metadata/status/etc is going to go to the wire. If it is false, it is not going to the wire because the call is already dead (i.e., canceled, deadline expired, other side dropped the channel, etc).
thanks
@nqf Does this answer the op's question? Aka. can this issue be closed now?
@nqf Does this answer the op's question? Aka. can this issue be closed now?
I have no more questions,I think you can close it
Hi Tradias,
Is there a way to detect a slowly receiving client in a long-lived streaming RPC in asio-grpc (or grpc itself)? I am working on a server application that sends data to clients using streaming RPCS, and I would like to detect slowly receiving clients and then drop the connection with them since it can lead to queuing up data on sockets, potentially resulting in slowing down the server or ooming it. Could such a mechanism be implemented with asio-grpc?
Thanks in advance.