userver: userver/ugrpc/client/response_future.hpp Source File
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages Concepts
response_future.hpp
Go to the documentation of this file.
1#pragma once
2
3/// @file userver/ugrpc/client/response_future.hpp
4/// @brief @copybrief ugrpc::client::ResponseFuture
5
6#include <userver/ugrpc/client/rpc.hpp>
7
8USERVER_NAMESPACE_BEGIN
9
10namespace ugrpc::client {
11
12/// @brief Controls a single request -> single response RPC.
13///
14/// This class is not thread-safe, it cannot be used from multiple tasks at the same time.
15///
16/// The RPC is cancelled on destruction unless the RPC is already finished. In
17/// that case the connection is not closed (it will be reused for new RPCs), and
18/// the server receives `RpcInterruptedError` immediately.
19template <typename Response>
20class [[nodiscard]] ResponseFuture final {
21 // Implementation note: further RPC controls (lazy Finish, ReadInitialMetadata), if needed in the future,
22 // should be added to UnaryCall, not to ResponseFuture. In that case UnaryCall should be exposed in GetCall.
23public:
24 ResponseFuture(ResponseFuture&&) noexcept = default;
25 ResponseFuture& operator=(ResponseFuture&&) noexcept = default;
26
27 /// @brief Checks if the asynchronous call has completed
28 /// Note, that once user gets result, IsReady should not be called
29 /// @return true if result ready
30 [[nodiscard]] bool IsReady() const noexcept { return call_.GetFinishFuture().IsReady(); }
31
32 /// @brief Await response until specified timepoint
33 ///
34 /// @throws ugrpc::client::RpcError on an RPC error
35 [[nodiscard]] engine::FutureStatus WaitUntil(engine::Deadline deadline) const {
36 return call_.GetFinishFuture().WaitUntil(deadline);
37 }
38
39 /// @brief Await and read the response
40 ///
41 /// `Get` should not be called multiple times for the same UnaryFuture.
42 ///
43 /// The connection is not closed, it will be reused for new RPCs.
44 ///
45 /// @returns the response on success
46 /// @throws ugrpc::client::RpcError on an RPC error
47 /// @throws ugrpc::client::RpcCancelledError on task cancellation
48 Response Get() { return call_.GetFinishFuture().Get(); }
49
50 /// @brief Get the original gRPC Call, useful e.g. for accessing metadata.
51 CallAnyBase& GetCall() { return call_; }
52
53 /// @overload
54 const CallAnyBase& GetCall() const { return call_; }
55
56 /// @cond
57 // For internal use only
58 template <typename Stub, typename Request>
59 ResponseFuture(
60 impl::CallParams&& params,
61 impl::PrepareUnaryCallProxy<Stub, Request, Response> prepare_unary_call,
62 const Request& request
63 )
64 : call_(std::move(params), prepare_unary_call, request) {}
65
66 // For internal use only.
67 engine::impl::ContextAccessor* TryGetContextAccessor() noexcept {
68 return call_.GetFinishFuture().TryGetContextAccessor();
69 }
70 /// @endcond
71
72private:
73 impl::UnaryCall<Response> call_;
74};
75
76} // namespace ugrpc::client
77
78USERVER_NAMESPACE_END