From 81dae117bee109e497f5d0187b6595f0cc931a27 Mon Sep 17 00:00:00 2001 From: qicosmos Date: Sun, 21 Nov 2021 11:42:31 +0800 Subject: [PATCH] fix broken promise --- include/rest_rpc/rpc_client.hpp | 39 +++++++++++++++++++++++++-------- 1 file changed, 30 insertions(+), 9 deletions(-) diff --git a/include/rest_rpc/rpc_client.hpp b/include/rest_rpc/rpc_client.hpp index 82fd751..b34deb3 100644 --- a/include/rest_rpc/rpc_client.hpp +++ b/include/rest_rpc/rpc_client.hpp @@ -46,6 +46,20 @@ private: std::string data_; }; +template +struct future_result { + uint64_t id; + std::future future; + template + std::future_status wait_for(const std::chrono::duration& rel_time) { + return future.wait_for(rel_time); + } + + T get() { + return future.get(); + } +}; + enum class CallModel { future, callback }; const constexpr auto FUTURE = CallModel::future; @@ -216,15 +230,17 @@ public: template typename std::enable_if::value>::type call(const std::string &rpc_name, Args &&...args) { - std::future future = + auto future_result = async_call(rpc_name, std::forward(args)...); - auto status = future.wait_for(std::chrono::milliseconds(TIMEOUT)); + auto status = future_result.wait_for(std::chrono::milliseconds(TIMEOUT)); if (status == std::future_status::timeout || status == std::future_status::deferred) { throw std::out_of_range("timeout or deferred"); } - future.get().as(); + future_result.get().as(); + std::unique_lock lock(cb_mtx_); + future_map_.erase(future_result.id); } template @@ -236,15 +252,20 @@ public: template typename std::enable_if::value, T>::type call(const std::string &rpc_name, Args &&...args) { - std::future future = + auto future_result = async_call(rpc_name, std::forward(args)...); - auto status = future.wait_for(std::chrono::milliseconds(TIMEOUT)); + auto status = future_result.wait_for(std::chrono::milliseconds(TIMEOUT)); if (status == std::future_status::timeout || status == std::future_status::deferred) { throw std::out_of_range("timeout or deferred"); } - return future.get().as(); + auto t = future_result.get().as(); + { + std::unique_lock lock(cb_mtx_); + future_map_.erase(future_result.id); + } + return t; } template @@ -255,7 +276,7 @@ public: #endif template - std::future async_call(const std::string &rpc_name, + future_result async_call(const std::string &rpc_name, Args &&...args) { auto p = std::make_shared>(); std::future future = p->get_future(); @@ -271,7 +292,7 @@ public: msgpack_codec codec; auto ret = codec.pack_args(rpc_name, std::forward(args)...); write(fu_id, request_type::req_res, std::move(ret)); - return future; + return future_result{ fu_id, std::move(future) }; } /** @@ -617,13 +638,13 @@ private: // LOG<set_value(req_result{ "" }); return; } } assert(f); f->set_value(req_result{data}); - future_map_.erase(req_id); } } }