cpp-msgpack-rpc 0.2.0
An RPC library implementing MessagePack RPC.
Loading...
Searching...
No Matches
call_future_impl.h
Go to the documentation of this file.
1/*
2 * Copyright 2023 MusicScience37 (Kenta Kabashima)
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
20#pragma once
21
22#include <algorithm>
23#include <chrono>
24#include <condition_variable>
25#include <memory>
26#include <mutex>
27#include <optional>
28#include <utility>
29
35
37
42class CallFutureImpl final
43 : public ICallFutureImpl,
44 public std::enable_shared_from_this<CallFutureImpl> {
45public:
51 explicit CallFutureImpl(std::chrono::steady_clock::time_point deadline)
52 : deadline_(deadline) {}
53
60 std::unique_lock<std::mutex> lock(is_set_mutex_);
61 if (is_set_) {
62 return;
63 }
64
65 result_.emplace(std::move(result));
66
67 is_set_ = true;
68 lock.unlock();
69 is_set_cond_var_.notify_all();
70 }
71
77 void set(const Status& error) {
78 std::unique_lock<std::mutex> lock(is_set_mutex_);
79 if (is_set_) {
80 return;
81 }
82
83 if (error.code() == StatusCode::SUCCESS) {
85 StatusCode::INVALID_ARGUMENT, "Invalid error status.");
86 }
87 status_ = error;
88
89 is_set_ = true;
90 lock.unlock();
91 is_set_cond_var_.notify_all();
92 }
93
95 [[nodiscard]] messages::CallResult get_result() override {
96 wait();
97 return get_result_impl();
98 }
99
102 std::chrono::nanoseconds timeout) override {
103 wait_for(timeout);
104 return get_result_impl();
105 }
106
107private:
112
118 void wait_for(std::chrono::nanoseconds timeout) {
119 const auto deadline = std::min<std::chrono::steady_clock::time_point>(
120 std::chrono::steady_clock::now() + timeout, deadline_);
121 wait_until_impl(deadline);
122 }
123
130 void wait_until_impl(std::chrono::steady_clock::time_point deadline) {
131 std::unique_lock<std::mutex> lock(is_set_mutex_);
132 if (!is_set_cond_var_.wait_until(
133 lock, deadline, [this] { return is_set_; })) {
134 throw MsgpackRPCException(StatusCode::TIMEOUT,
135 "Result of an RPC couldn't be received within a timeout.");
136 }
137 }
138
145 if (result_) {
146 return *result_;
147 }
149 }
150
152 std::optional<messages::CallResult> result_{};
153
156
158 bool is_set_{false};
159
161 std::chrono::steady_clock::time_point deadline_;
162
170 std::mutex is_set_mutex_{};
171
173 std::condition_variable is_set_cond_var_{};
174};
175
176} // namespace msgpack_rpc::clients::impl
Definition of CallResult class.
messages::CallResult get_result_within(std::chrono::nanoseconds timeout) override
Get the result of RPC within a timeout.
void wait_until_impl(std::chrono::steady_clock::time_point deadline)
Wait the result until the given deadline without consideration of the deadline of the RPC.
std::chrono::steady_clock::time_point deadline_
Deadline of the result of the RPC.
messages::CallResult get_result() override
Get the result of RPC.
void wait_for(std::chrono::nanoseconds timeout)
Wait the result for the given time.
CallFutureImpl(std::chrono::steady_clock::time_point deadline)
Constructor.
void set(messages::CallResult result)
Set a result.
bool is_set_
Whether a result or an error is set.
std::optional< messages::CallResult > result_
Result of the RPC.
messages::CallResult get_result_impl()
Get the result assuming the result is already set.
std::condition_variable is_set_cond_var_
Condition variable for notifying change of is_set_.
void set(const Status &error)
Set an error.
Class of exceptions in cpp-msgpack-rpc library.
Class of statuses.
Definition status.h:34
StatusCode code() const noexcept
Get the status code.
Definition status.cpp:69
Class of results of methods.
Definition call_result.h:35
Definition of ICallFutureImpl class.
Definition of MsgpackRPCException class.
Namespace of internal implementations.
Definition of Status class.
Definition of StatusCode enumeration.