aboutsummaryrefslogtreecommitdiffhomepage
path: root/tdactor
diff options
context:
space:
mode:
authorlevlam <levlam@telegram.org>2022-06-27 13:30:18 +0300
committerlevlam <levlam@telegram.org>2022-06-27 13:30:18 +0300
commit32bac7bd24202c717a7f4ae119cc7dec48d4b83a (patch)
tree47f047b268e8c268a67808e99247e1edda2d7d3b /tdactor
parentda2e504566d5f8397c4eef573f4e4931ca6a9bef (diff)
Move Promise to tdutils.
Diffstat (limited to 'tdactor')
-rw-r--r--tdactor/td/actor/MultiPromise.cpp2
-rw-r--r--tdactor/td/actor/MultiPromise.h1
-rw-r--r--tdactor/td/actor/PromiseFuture.h385
-rw-r--r--tdactor/td/actor/SleepActor.h2
-rw-r--r--tdactor/test/actors_simple.cpp1
5 files changed, 7 insertions, 384 deletions
diff --git a/tdactor/td/actor/MultiPromise.cpp b/tdactor/td/actor/MultiPromise.cpp
index 5bf8d40bd..f78e0f016 100644
--- a/tdactor/td/actor/MultiPromise.cpp
+++ b/tdactor/td/actor/MultiPromise.cpp
@@ -28,7 +28,7 @@ Promise<Unit> MultiPromiseActor::get_promise() {
future.set_event(EventCreator::raw(actor_id(), nullptr));
futures_.emplace_back(std::move(future));
LOG(DEBUG) << "Get promise #" << futures_.size() << " for " << name_;
- return PromiseCreator::from_promise_actor(std::move(promise));
+ return create_promise_from_promise_actor(std::move(promise));
}
void MultiPromiseActor::raw_event(const Event::Raw &event) {
diff --git a/tdactor/td/actor/MultiPromise.h b/tdactor/td/actor/MultiPromise.h
index 88ac09e52..73b24d5d1 100644
--- a/tdactor/td/actor/MultiPromise.h
+++ b/tdactor/td/actor/MultiPromise.h
@@ -10,6 +10,7 @@
#include "td/actor/PromiseFuture.h"
#include "td/utils/common.h"
+#include "td/utils/Promise.h"
#include "td/utils/Status.h"
namespace td {
diff --git a/tdactor/td/actor/PromiseFuture.h b/tdactor/td/actor/PromiseFuture.h
index fb81bced1..1a8940558 100644
--- a/tdactor/td/actor/PromiseFuture.h
+++ b/tdactor/td/actor/PromiseFuture.h
@@ -8,282 +8,10 @@
#include "td/actor/actor.h"
-#include "td/utils/CancellationToken.h"
-#include "td/utils/Closure.h"
#include "td/utils/common.h"
-#include "td/utils/invoke.h"
-#include "td/utils/logging.h"
-#include "td/utils/MovableValue.h"
-#include "td/utils/ScopeGuard.h"
-#include "td/utils/Status.h"
-
-#include <tuple>
-#include <type_traits>
-#include <utility>
+#include "td/utils/Promise.h"
namespace td {
-
-template <class T = Unit>
-class PromiseInterface {
- public:
- PromiseInterface() = default;
- PromiseInterface(const PromiseInterface &) = delete;
- PromiseInterface &operator=(const PromiseInterface &) = delete;
- PromiseInterface(PromiseInterface &&) = default;
- PromiseInterface &operator=(PromiseInterface &&) = default;
- virtual ~PromiseInterface() = default;
-
- virtual void set_value(T &&value) {
- set_result(std::move(value));
- }
- virtual void set_error(Status &&error) {
- set_result(std::move(error));
- }
- virtual void set_result(Result<T> &&result) {
- if (result.is_ok()) {
- set_value(result.move_as_ok());
- } else {
- set_error(result.move_as_error());
- }
- }
-
- virtual bool is_cancellable() const {
- return false;
- }
- virtual bool is_canceled() const {
- return false;
- }
-};
-
-namespace detail {
-
-template <typename T>
-struct GetArg final : public GetArg<decltype(&T::operator())> {};
-
-template <class C, class R, class Arg>
-class GetArg<R (C::*)(Arg)> {
- public:
- using type = Arg;
-};
-template <class C, class R, class Arg>
-class GetArg<R (C::*)(Arg) const> {
- public:
- using type = Arg;
-};
-
-template <class T>
-using get_arg_t = std::decay_t<typename GetArg<T>::type>;
-
-template <class T>
-struct DropResult {
- using type = T;
-};
-
-template <class T>
-struct DropResult<Result<T>> {
- using type = T;
-};
-
-template <class T>
-using drop_result_t = typename DropResult<T>::type;
-
-template <class ValueT, class FunctionT>
-class LambdaPromise : public PromiseInterface<ValueT> {
- enum class State : int32 { Empty, Ready, Complete };
-
- public:
- void set_value(ValueT &&value) override {
- CHECK(state_.get() == State::Ready);
- func_(std::move(value));
- state_ = State::Complete;
- }
-
- void set_error(Status &&error) override {
- if (state_.get() == State::Ready) {
- do_error(std::move(error));
- state_ = State::Complete;
- }
- }
- LambdaPromise(const LambdaPromise &other) = delete;
- LambdaPromise &operator=(const LambdaPromise &other) = delete;
- LambdaPromise(LambdaPromise &&other) = default;
- LambdaPromise &operator=(LambdaPromise &&other) = default;
- ~LambdaPromise() override {
- if (state_.get() == State::Ready) {
- do_error(Status::Error("Lost promise"));
- }
- }
-
- template <class FromT>
- explicit LambdaPromise(FromT &&func) : func_(std::forward<FromT>(func)), state_(State::Ready) {
- }
-
- private:
- FunctionT func_;
- MovableValue<State> state_{State::Empty};
-
- template <class F = FunctionT>
- std::enable_if_t<is_callable<F, Result<ValueT>>::value, void> do_error(Status &&status) {
- func_(Result<ValueT>(std::move(status)));
- }
- template <class Y, class F = FunctionT>
- std::enable_if_t<!is_callable<F, Result<ValueT>>::value, void> do_error(Y &&status) {
- func_(Auto());
- }
-};
-} // namespace detail
-
-template <class T>
-class SafePromise;
-
-template <class T = Unit>
-class Promise;
-
-template <class T>
-struct is_promise_interface : std::false_type {};
-
-template <class U>
-struct is_promise_interface<PromiseInterface<U>> : std::true_type {};
-
-template <class U>
-struct is_promise_interface<Promise<U>> : std::true_type {};
-
-template <class T>
-struct is_promise_interface_ptr : std::false_type {};
-
-template <class U>
-struct is_promise_interface_ptr<unique_ptr<U>> : std::true_type {};
-
-template <class T = void, class F = void, std::enable_if_t<std::is_same<T, void>::value, bool> has_t = false>
-auto lambda_promise(F &&f) {
- return detail::LambdaPromise<detail::drop_result_t<detail::get_arg_t<std::decay_t<F>>>, std::decay_t<F>>(
- std::forward<F>(f));
-}
-template <class T = void, class F = void, std::enable_if_t<!std::is_same<T, void>::value, bool> has_t = true>
-auto lambda_promise(F &&f) {
- return detail::LambdaPromise<T, std::decay_t<F>>(std::forward<F>(f));
-}
-
-template <class T, class F,
- std::enable_if_t<is_promise_interface<std::decay_t<F>>::value, bool> from_promise_interface = true>
-auto &&promise_interface(F &&f) {
- return std::forward<F>(f);
-}
-
-template <class T, class F,
- std::enable_if_t<!is_promise_interface<std::decay_t<F>>::value, bool> from_promise_interface = false>
-auto promise_interface(F &&f) {
- return lambda_promise<T>(std::forward<F>(f));
-}
-
-template <class T, class F,
- std::enable_if_t<is_promise_interface_ptr<std::decay_t<F>>::value, bool> from_promise_interface = true>
-auto promise_interface_ptr(F &&f) {
- return std::forward<F>(f);
-}
-
-template <class T, class F,
- std::enable_if_t<!is_promise_interface_ptr<std::decay_t<F>>::value, bool> from_promise_interface = false>
-auto promise_interface_ptr(F &&f) {
- return td::make_unique<std::decay_t<decltype(promise_interface<T>(std::forward<F>(f)))>>(
- promise_interface<T>(std::forward<F>(f)));
-}
-
-template <class T>
-class Promise {
- public:
- void set_value(T &&value) {
- if (!promise_) {
- return;
- }
- promise_->set_value(std::move(value));
- promise_.reset();
- }
- void set_error(Status &&error) {
- if (!promise_) {
- return;
- }
- promise_->set_error(std::move(error));
- promise_.reset();
- }
- void set_result(Result<T> &&result) {
- if (!promise_) {
- return;
- }
- promise_->set_result(std::move(result));
- promise_.reset();
- }
- void reset() {
- promise_.reset();
- }
- bool is_cancellable() const {
- if (!promise_) {
- return false;
- }
- return promise_->is_cancellable();
- }
- bool is_canceled() const {
- if (!promise_) {
- return false;
- }
- return promise_->is_canceled();
- }
- unique_ptr<PromiseInterface<T>> release() {
- return std::move(promise_);
- }
-
- Promise() = default;
- explicit Promise(unique_ptr<PromiseInterface<T>> promise) : promise_(std::move(promise)) {
- }
- Promise(Auto) {
- }
- Promise(SafePromise<T> &&other);
- Promise &operator=(SafePromise<T> &&other);
- template <class F, std::enable_if_t<!std::is_same<std::decay_t<F>, Promise>::value, int> = 0>
- Promise(F &&f) : promise_(promise_interface_ptr<T>(std::forward<F>(f))) {
- }
-
- explicit operator bool() {
- return static_cast<bool>(promise_);
- }
-
- private:
- unique_ptr<PromiseInterface<T>> promise_;
-};
-
-
-template <class T = Unit>
-class SafePromise {
- public:
- SafePromise(Promise<T> promise, Result<T> result) : promise_(std::move(promise)), result_(std::move(result)) {
- }
- SafePromise(const SafePromise &other) = delete;
- SafePromise &operator=(const SafePromise &other) = delete;
- SafePromise(SafePromise &&other) = default;
- SafePromise &operator=(SafePromise &&other) = default;
- ~SafePromise() {
- if (promise_) {
- promise_.set_result(std::move(result_));
- }
- }
- Promise<T> release() {
- return std::move(promise_);
- }
-
- private:
- Promise<T> promise_;
- Result<T> result_;
-};
-
-template <class T>
-Promise<T>::Promise(SafePromise<T> &&other) : Promise(other.release()) {
-}
-template <class T>
-Promise<T> &Promise<T>::operator=(SafePromise<T> &&other) {
- *this = other.release();
- return *this;
-}
-
namespace detail {
class EventPromise final : public PromiseInterface<Unit> {
@@ -323,40 +51,6 @@ class EventPromise final : public PromiseInterface<Unit> {
}
}
};
-
-template <class PromiseT>
-class CancellablePromise final : public PromiseT {
- public:
- template <class... ArgsT>
- CancellablePromise(CancellationToken cancellation_token, ArgsT &&...args)
- : PromiseT(std::forward<ArgsT>(args)...), cancellation_token_(std::move(cancellation_token)) {
- }
- bool is_cancellable() const final {
- return true;
- }
- bool is_canceled() const final {
- return static_cast<bool>(cancellation_token_);
- }
-
- private:
- CancellationToken cancellation_token_;
-};
-
-template <class... ArgsT>
-class JoinPromise final : public PromiseInterface<Unit> {
- public:
- explicit JoinPromise(ArgsT &&...arg) : promises_(std::forward<ArgsT>(arg)...) {
- }
- void set_value(Unit &&) final {
- tuple_for_each(promises_, [](auto &promise) { promise.set_value(Unit()); });
- }
- void set_error(Status &&error) final {
- tuple_for_each(promises_, [&error](auto &promise) { promise.set_error(error.clone()); });
- }
-
- private:
- std::tuple<std::decay_t<ArgsT>...> promises_;
-};
} // namespace detail
inline Promise<Unit> create_event_promise(EventFull &&ok) {
@@ -367,31 +61,6 @@ inline Promise<Unit> create_event_promise(EventFull ok, EventFull fail) {
return Promise<Unit>(td::make_unique<detail::EventPromise>(std::move(ok), std::move(fail)));
}
-class SendClosure {
- public:
- template <class... ArgsT>
- void operator()(ArgsT &&...args) const {
- send_closure(std::forward<ArgsT>(args)...);
- }
-};
-
-//template <class T>
-//template <class... ArgsT>
-//auto Promise<T>::send_closure(ArgsT &&... args) {
-// return [promise = std::move(*this), t = std::make_tuple(std::forward<ArgsT>(args)...)](auto &&r_res) mutable {
-// TRY_RESULT_PROMISE(promise, res, std::move(r_res));
-// td2::call_tuple(SendClosure(), std::tuple_cat(std::move(t), std::make_tuple(std::move(res), std::move(promise))));
-// };
-//}
-
-template <class... ArgsT>
-auto promise_send_closure(ArgsT &&...args) {
- return [t = std::make_tuple(std::forward<ArgsT>(args)...)](auto &&res) mutable {
- call_tuple(SendClosure(), std::tuple_cat(std::move(t), std::make_tuple(std::forward<decltype(res)>(res))));
- };
-}
-
-/*** FutureActor and PromiseActor ***/
template <class T>
class FutureActor;
@@ -618,57 +287,9 @@ FutureActor<T> send_promise(ActorId<ActorAT> actor_id, ResultT (ActorBT::*func)(
return pf.move_future();
}
-class PromiseCreator {
- public:
- template <class OkT, class ArgT = detail::drop_result_t<detail::get_arg_t<OkT>>>
- static Promise<ArgT> lambda(OkT &&ok) {
- return Promise<ArgT>(td::make_unique<detail::LambdaPromise<ArgT, std::decay_t<OkT>>>(std::forward<OkT>(ok)));
- }
-
- template <class OkT, class ArgT = detail::drop_result_t<detail::get_arg_t<OkT>>>
- static auto cancellable_lambda(CancellationToken cancellation_token, OkT &&ok) {
- return Promise<ArgT>(td::make_unique<detail::CancellablePromise<detail::LambdaPromise<ArgT, std::decay_t<OkT>>>>(
- std::move(cancellation_token), std::forward<OkT>(ok)));
- }
-
- template <class... ArgsT>
- static Promise<> join(ArgsT &&...args) {
- return Promise<>(td::make_unique<detail::JoinPromise<ArgsT...>>(std::forward<ArgsT>(args)...));
- }
-
- template <class T>
- static Promise<T> from_promise_actor(PromiseActor<T> &&from) {
- return Promise<T>(td::make_unique<PromiseActor<T>>(std::move(from)));
- }
-};
-
-inline void set_promises(vector<Promise<Unit>> &promises) {
- auto moved_promises = std::move(promises);
- promises.clear();
-
- for (auto &promise : moved_promises) {
- promise.set_value(Unit());
- }
-}
-
template <class T>
-void fail_promises(vector<Promise<T>> &promises, Status &&error) {
- CHECK(error.is_error());
- auto moved_promises = std::move(promises);
- promises.clear();
-
- auto size = moved_promises.size();
- if (size == 0) {
- return;
- }
- size--;
- for (size_t i = 0; i < size; i++) {
- auto &promise = moved_promises[i];
- if (promise) {
- promise.set_error(error.clone());
- }
- }
- moved_promises[size].set_error(std::move(error));
+Promise<T> create_promise_from_promise_actor(PromiseActor<T> &&from) {
+ return Promise<T>(td::make_unique<PromiseActor<T>>(std::move(from)));
}
} // namespace td
diff --git a/tdactor/td/actor/SleepActor.h b/tdactor/td/actor/SleepActor.h
index 2c02db8af..8682ab0df 100644
--- a/tdactor/td/actor/SleepActor.h
+++ b/tdactor/td/actor/SleepActor.h
@@ -7,9 +7,9 @@
#pragma once
#include "td/actor/actor.h"
-#include "td/actor/PromiseFuture.h"
#include "td/utils/common.h"
+#include "td/utils/Promise.h"
namespace td {
diff --git a/tdactor/test/actors_simple.cpp b/tdactor/test/actors_simple.cpp
index a76b80884..58f14ac48 100644
--- a/tdactor/test/actors_simple.cpp
+++ b/tdactor/test/actors_simple.cpp
@@ -16,6 +16,7 @@
#include "td/utils/Observer.h"
#include "td/utils/port/FileFd.h"
#include "td/utils/port/thread.h"
+#include "td/utils/Promise.h"
#include "td/utils/Slice.h"
#include "td/utils/Status.h"
#include "td/utils/StringBuilder.h"