diff options
author | Wyatt Hepler <hepler@google.com> | 2023-04-11 01:27:36 +0000 |
---|---|---|
committer | CQ Bot Account <pigweed-scoped@luci-project-accounts.iam.gserviceaccount.com> | 2023-04-11 01:27:36 +0000 |
commit | e850621049d267fbf5b78f9eb3f9b4895cdc4c92 (patch) | |
tree | 30504cb2541225f129353f84d3658b04fed96a5a /pw_rpc/public/pw_rpc/synchronous_call.h | |
parent | 3ceb704d2101ba27e064886414447b3365ca8f47 (diff) | |
download | pigweed-e850621049d267fbf5b78f9eb3f9b4895cdc4c92.tar.gz |
pw_rpc: Raw synchronous call API
Raw synchronous calls pass the raw response buffer to a callback
function.
Fixes: b/268216599
Change-Id: I0f9462e5d5baa987f754615c3156942e05f9215f
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/128371
Reviewed-by: Xiaofan Jiang <xiaofanj@google.com>
Reviewed-by: Alexei Frolov <frolv@google.com>
Commit-Queue: Auto-Submit <auto-submit@pigweed.google.com.iam.gserviceaccount.com>
Pigweed-Auto-Submit: Wyatt Hepler <hepler@google.com>
Diffstat (limited to 'pw_rpc/public/pw_rpc/synchronous_call.h')
-rw-r--r-- | pw_rpc/public/pw_rpc/synchronous_call.h | 126 |
1 files changed, 114 insertions, 12 deletions
diff --git a/pw_rpc/public/pw_rpc/synchronous_call.h b/pw_rpc/public/pw_rpc/synchronous_call.h index 92bd20217..8a2be800a 100644 --- a/pw_rpc/public/pw_rpc/synchronous_call.h +++ b/pw_rpc/public/pw_rpc/synchronous_call.h @@ -25,25 +25,28 @@ /// /// `pw_rpc` provides wrappers that convert the asynchronous client API to a /// synchronous API. The `SynchronousCall<RpcMethod>` functions wrap the -/// asynchronous client RPC call with a timed thread notification and return -/// once a result is known or a timeout has occurred. These return a -/// `SynchronousCallResult<Response>` object, which can be queried to determine -/// whether any error scenarios occurred and, if not, access the response. +/// asynchronous client RPC call with a timed thread notification and returns +/// once a result is known or a timeout has occurred. Only unary methods are +/// supported. +/// +/// The Nanopb and pwpb APIs return a `SynchronousCallResult<Response>` object, +/// which can be queried to determine whether any error scenarios occurred and, +/// if not, access the response. The raw API executes a function when the call +/// completes or returns a `pw::Status` if it does not. /// /// `SynchronousCall<RpcMethod>` blocks indefinitely, whereas /// `SynchronousCallFor<RpcMethod>` and `SynchronousCallUntil<RpcMethod>` block /// for a given timeout or until a deadline, respectively. All wrappers work -/// with both the standalone static RPC functions and the generated Client -/// member methods. +/// with either the standalone static RPC functions or the generated service +/// client member methods. /// /// @note Use of the SynchronousCall wrappers requires a /// @cpp_class{pw::sync::TimedThreadNotification} backend. /// -/// @note Only nanopb and pw_protobuf unary RPC methods are supported. -/// -/// The following example blocks indefinitely. If you'd like to include a -/// timeout for how long the call should block for, use the -/// `SynchronousCallFor()` or `SynchronousCallUntil()` variants. +/// The following examples use the Nanopb API to make a call that blocks +/// indefinitely. If you'd like to include a timeout for how long the call +/// should block for, use the `SynchronousCallFor()` or `SynchronousCallUntil()` +/// variants. /// /// @code{.cpp} /// pw_rpc_EchoMessage request{.msg = "hello" }; @@ -58,7 +61,7 @@ /// /// Additionally, the use of a generated `Client` object is supported: /// -/// @code +/// @code{.cpp} /// pw_rpc::nanopb::EchoService::Client client(rpc_client, channel_id); /// pw_rpc_EchoMessage request{.msg = "hello" }; /// pw::rpc::SynchronousCallResult<pw_rpc_EchoMessage> result = @@ -69,6 +72,22 @@ /// } /// @endcode /// +/// The raw API works similarly to the Nanopb API, but takes a +/// @cpp_type{pw::Function} and returns a @cpp_class{pw::Status}. If the RPC +/// completes, the @cpp_type{pw::Function} is called with the response and +/// returned status, and the `SynchronousCall` invocation returns +/// @pw_status{OK}. If the RPC fails, `SynchronousCall` returns an error. +/// +/// @code{.cpp} +/// pw::Status rpc_status = pw::rpc::SynchronousCall<EchoService::Echo>( +/// rpc_client, channel_id, encoded_request, +/// [](pw::ConstByteSpan reply, pw::Status status) { +/// PW_LOG_INFO("Received %zu bytes with status %s", +/// reply.size(), +/// status.str()); +/// }); +/// @endcode +/// /// @warning These wrappers should not be used from any context that cannot be /// blocked! This method will block the calling thread until the RPC completes, /// and translate the response into a `pw::rpc::SynchronousCallResult` that @@ -134,6 +153,30 @@ SynchronousCall( return std::move(call_state.result); } +/// Invokes a unary RPC synchronously using the raw API. Blocks until a +/// response is received. +template <auto kRpcMethod> +Status SynchronousCall(Client& client, + uint32_t channel_id, + ConstByteSpan request, + Function<void(ConstByteSpan, Status)>&& on_completed) { + return internal::RawSynchronousCall<kRpcMethod>( + std::move(on_completed), + internal::CallFreeFunction<kRpcMethod>(client, channel_id, request)); +} + +/// Invokes a unary RPC synchronously using the raw API. Blocks until a +/// response is received. +template <auto kRpcMethod> +Status SynchronousCall( + const typename internal::MethodInfo<kRpcMethod>::GeneratedClient& client, + ConstByteSpan request, + Function<void(ConstByteSpan, Status)>&& on_completed) { + return internal::RawSynchronousCall<kRpcMethod>( + std::move(on_completed), + internal::CallGeneratedClient<kRpcMethod>(client, request)); +} + /// Invokes a unary RPC synchronously using Nanopb or pwpb. Blocks until a /// response is received or the provided timeout passes. /// @@ -201,6 +244,35 @@ SynchronousCallFor( return std::move(call_state.result); } +/// Invokes a unary RPC synchronously using the raw API. Blocks until a +/// response is received or the provided timeout passes. +template <auto kRpcMethod> +Status SynchronousCallFor( + Client& client, + uint32_t channel_id, + ConstByteSpan request, + chrono::SystemClock::duration timeout, + Function<void(ConstByteSpan, Status)>&& on_completed) { + return internal::RawSynchronousCall<kRpcMethod>( + std::move(on_completed), + internal::CallFreeFunction<kRpcMethod>(client, channel_id, request), + timeout); +} + +/// Invokes a unary RPC synchronously using the raw API. Blocks until a +/// response is received or the provided timeout passes. +template <auto kRpcMethod> +Status SynchronousCallFor( + const typename internal::MethodInfo<kRpcMethod>::GeneratedClient& client, + ConstByteSpan request, + chrono::SystemClock::duration timeout, + Function<void(ConstByteSpan, Status)>&& on_completed) { + return internal::RawSynchronousCall<kRpcMethod>( + std::move(on_completed), + internal::CallGeneratedClient<kRpcMethod>(client, request), + timeout); +} + /// Invokes a unary RPC synchronously using Nanopb or pwpb. Blocks until a /// response is received or the provided deadline arrives. /// @@ -267,4 +339,34 @@ SynchronousCallUntil( return std::move(call_state.result); } + +/// Invokes a unary RPC synchronously using the raw API. Blocks until a +/// response is received or the provided deadline arrives. +template <auto kRpcMethod> +Status SynchronousCallUntil( + Client& client, + uint32_t channel_id, + ConstByteSpan request, + chrono::SystemClock::time_point deadline, + Function<void(ConstByteSpan, Status)>&& on_completed) { + return internal::RawSynchronousCall<kRpcMethod>( + std::move(on_completed), + internal::CallFreeFunction<kRpcMethod>(client, channel_id, request), + deadline); +} + +/// Invokes a unary RPC synchronously using the raw API. Blocks until a +/// response is received or the provided deadline arrives. +template <auto kRpcMethod> +Status SynchronousCallUntil( + const typename internal::MethodInfo<kRpcMethod>::GeneratedClient& client, + ConstByteSpan request, + chrono::SystemClock::time_point deadline, + Function<void(ConstByteSpan, Status)>&& on_completed) { + return internal::RawSynchronousCall<kRpcMethod>( + std::move(on_completed), + internal::CallGeneratedClient<kRpcMethod>(client, request), + deadline); +} + } // namespace pw::rpc |