pw_rpc: Prepare Call for use by both server & client
- Introduce ServerCall and ClientCall classes for functionality not
shared between client and server calls.
- Move the on_client_stream_end_ / on_completed_ callbacks to ServerCall
and ClientCall classes, since these callbacks differ between server
and client.
- Use CallContext only to initialize calls. Do not store the CallContext
in the Call class, since the method and service are not needed in the
call and are not relevant for the client.
- Move prior call cancellation from the Server to the RegisterCall
function in Endpoint. This correctly cancels prior calls when using
the Open API, and the code will be shared between server & client.
- Expand and update raw and Nanopb method tests.
- Remove redundant Method argument from the Method Invoker function. The
method is included in the CallContext.
Change-Id: I6ff46d2a22028d05acd1bbc15e925def1dcbc263
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/61796
Pigweed-Auto-Submit: Wyatt Hepler <hepler@google.com>
Commit-Queue: Auto-Submit <auto-submit@pigweed.google.com.iam.gserviceaccount.com>
Reviewed-by: Keir Mierle <keir@google.com>
diff --git a/pw_rpc/server.cc b/pw_rpc/server.cc
index 7424288..b67742c 100644
--- a/pw_rpc/server.cc
+++ b/pw_rpc/server.cc
@@ -33,8 +33,9 @@
Status Server::ProcessPacket(std::span<const byte> data,
ChannelOutput& interface) {
- internal::Call* call;
- Result<Packet> result = Endpoint::ProcessPacket(data, Packet::kServer, call);
+ internal::Call* base;
+ Result<Packet> result = Endpoint::ProcessPacket(data, Packet::kServer, base);
+ internal::ServerCall* const call = static_cast<internal::ServerCall*>(base);
if (!result.ok()) {
return result.status();
@@ -72,12 +73,9 @@
switch (packet.type()) {
case PacketType::REQUEST: {
- // If the REQUEST is for an ongoing RPC, cancel it, then call it again.
- if (call != nullptr) {
- call->HandleError(Status::Cancelled());
- }
-
- internal::CallContext context(*this, *channel, *service, *method);
+ // If the REQUEST is for an ongoing RPC, the existing call will be
+ // cancelled when the new call object is created.
+ const internal::CallContext context(*this, *channel, *service, *method);
method->Invoke(context, packet);
break;
}
@@ -120,7 +118,7 @@
void Server::HandleClientStreamPacket(const internal::Packet& packet,
internal::Channel& channel,
- internal::Call* call) const {
+ internal::ServerCall* call) const {
if (call == nullptr) {
PW_LOG_DEBUG(
"Received client stream packet for method that is not pending");
@@ -150,7 +148,7 @@
void Server::HandleCancelPacket(const Packet& packet,
internal::Channel& channel,
- internal::Call* call) const {
+ internal::ServerCall* call) const {
if (call == nullptr) {
channel.Send(Packet::ServerError(packet, Status::FailedPrecondition()))
.IgnoreError(); // TODO(pwbug/387): Handle Status properly