2018-12-31 20:04:05 +01:00
|
|
|
//
|
2022-12-31 22:28:08 +01:00
|
|
|
// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023
|
2018-12-31 20:04:05 +01:00
|
|
|
//
|
|
|
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
|
|
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|
|
|
//
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include "td/actor/actor.h"
|
|
|
|
#include "td/actor/PromiseFuture.h"
|
|
|
|
|
|
|
|
#include "td/utils/common.h"
|
2022-06-27 12:30:18 +02:00
|
|
|
#include "td/utils/Promise.h"
|
2018-12-31 20:04:05 +01:00
|
|
|
#include "td/utils/Status.h"
|
|
|
|
|
|
|
|
namespace td {
|
|
|
|
|
|
|
|
class MultiPromiseInterface {
|
|
|
|
public:
|
|
|
|
virtual void add_promise(Promise<> &&promise) = 0;
|
|
|
|
virtual Promise<> get_promise() = 0;
|
|
|
|
|
|
|
|
virtual size_t promise_count() const = 0;
|
|
|
|
virtual void set_ignore_errors(bool ignore_errors) = 0;
|
|
|
|
|
|
|
|
MultiPromiseInterface() = default;
|
|
|
|
MultiPromiseInterface(const MultiPromiseInterface &) = delete;
|
|
|
|
MultiPromiseInterface &operator=(const MultiPromiseInterface &) = delete;
|
|
|
|
MultiPromiseInterface(MultiPromiseInterface &&) = default;
|
|
|
|
MultiPromiseInterface &operator=(MultiPromiseInterface &&) = default;
|
|
|
|
virtual ~MultiPromiseInterface() = default;
|
|
|
|
};
|
|
|
|
|
2021-07-04 04:58:54 +02:00
|
|
|
class MultiPromise final : public MultiPromiseInterface {
|
2018-12-31 20:04:05 +01:00
|
|
|
public:
|
2021-07-03 22:51:36 +02:00
|
|
|
void add_promise(Promise<> &&promise) final {
|
2018-12-31 20:04:05 +01:00
|
|
|
impl_->add_promise(std::move(promise));
|
|
|
|
}
|
2021-07-03 22:51:36 +02:00
|
|
|
Promise<> get_promise() final {
|
2018-12-31 20:04:05 +01:00
|
|
|
return impl_->get_promise();
|
|
|
|
}
|
|
|
|
|
2021-07-03 22:51:36 +02:00
|
|
|
size_t promise_count() const final {
|
2018-12-31 20:04:05 +01:00
|
|
|
return impl_->promise_count();
|
|
|
|
}
|
2021-07-03 22:51:36 +02:00
|
|
|
void set_ignore_errors(bool ignore_errors) final {
|
2018-12-31 20:04:05 +01:00
|
|
|
impl_->set_ignore_errors(ignore_errors);
|
|
|
|
}
|
|
|
|
|
|
|
|
MultiPromise() = default;
|
2018-09-27 03:19:03 +02:00
|
|
|
explicit MultiPromise(unique_ptr<MultiPromiseInterface> impl) : impl_(std::move(impl)) {
|
2018-12-31 20:04:05 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
2018-09-27 03:19:03 +02:00
|
|
|
unique_ptr<MultiPromiseInterface> impl_;
|
2018-12-31 20:04:05 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
class MultiPromiseActor final
|
|
|
|
: public Actor
|
|
|
|
, public MultiPromiseInterface {
|
|
|
|
public:
|
2018-12-12 18:02:50 +01:00
|
|
|
explicit MultiPromiseActor(string name) : name_(std::move(name)) {
|
2018-12-12 00:48:56 +01:00
|
|
|
}
|
2018-12-31 20:04:05 +01:00
|
|
|
|
2021-07-03 22:51:36 +02:00
|
|
|
void add_promise(Promise<Unit> &&promise) final;
|
2018-12-31 20:04:05 +01:00
|
|
|
|
2021-07-03 22:51:36 +02:00
|
|
|
Promise<Unit> get_promise() final;
|
2018-12-31 20:04:05 +01:00
|
|
|
|
2021-07-03 22:51:36 +02:00
|
|
|
void set_ignore_errors(bool ignore_errors) final;
|
2018-12-31 20:04:05 +01:00
|
|
|
|
2021-07-03 22:51:36 +02:00
|
|
|
size_t promise_count() const final;
|
2018-12-31 20:04:05 +01:00
|
|
|
|
|
|
|
private:
|
|
|
|
void set_result(Result<Unit> &&result);
|
|
|
|
|
2018-12-12 18:02:50 +01:00
|
|
|
string name_;
|
2018-12-31 20:04:05 +01:00
|
|
|
vector<Promise<Unit>> promises_; // promises waiting for result
|
|
|
|
vector<FutureActor<Unit>> futures_; // futures waiting for result of the queries
|
|
|
|
size_t received_results_ = 0;
|
|
|
|
bool ignore_errors_ = false;
|
2020-06-05 05:52:55 +02:00
|
|
|
Result<Unit> result_;
|
2018-12-31 20:04:05 +01:00
|
|
|
|
2021-07-03 22:51:36 +02:00
|
|
|
void raw_event(const Event::Raw &event) final;
|
2018-12-31 20:04:05 +01:00
|
|
|
|
2021-07-03 22:51:36 +02:00
|
|
|
void tear_down() final;
|
2020-06-05 05:52:55 +02:00
|
|
|
|
2021-07-03 22:51:36 +02:00
|
|
|
void on_start_migrate(int32) final {
|
2018-12-31 20:04:05 +01:00
|
|
|
UNREACHABLE();
|
|
|
|
}
|
2021-07-03 22:51:36 +02:00
|
|
|
void on_finish_migrate() final {
|
2018-12-31 20:04:05 +01:00
|
|
|
UNREACHABLE();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2021-11-03 16:05:53 +01:00
|
|
|
template <>
|
|
|
|
class ActorTraits<MultiPromiseActor> {
|
|
|
|
public:
|
|
|
|
static constexpr bool need_context = false;
|
|
|
|
static constexpr bool need_start_up = true;
|
|
|
|
};
|
|
|
|
|
2021-07-04 04:58:54 +02:00
|
|
|
class MultiPromiseActorSafe final : public MultiPromiseInterface {
|
2018-12-31 20:04:05 +01:00
|
|
|
public:
|
2021-07-03 22:51:36 +02:00
|
|
|
void add_promise(Promise<Unit> &&promise) final;
|
|
|
|
Promise<Unit> get_promise() final;
|
|
|
|
void set_ignore_errors(bool ignore_errors) final;
|
|
|
|
size_t promise_count() const final;
|
2018-12-12 18:02:50 +01:00
|
|
|
explicit MultiPromiseActorSafe(string name) : multi_promise_(td::make_unique<MultiPromiseActor>(std::move(name))) {
|
2018-12-12 00:48:56 +01:00
|
|
|
}
|
2018-12-31 20:04:05 +01:00
|
|
|
MultiPromiseActorSafe(const MultiPromiseActorSafe &other) = delete;
|
|
|
|
MultiPromiseActorSafe &operator=(const MultiPromiseActorSafe &other) = delete;
|
|
|
|
MultiPromiseActorSafe(MultiPromiseActorSafe &&other) = delete;
|
|
|
|
MultiPromiseActorSafe &operator=(MultiPromiseActorSafe &&other) = delete;
|
2021-07-03 22:51:36 +02:00
|
|
|
~MultiPromiseActorSafe() final;
|
2018-12-31 20:04:05 +01:00
|
|
|
|
|
|
|
private:
|
2018-12-12 00:48:56 +01:00
|
|
|
unique_ptr<MultiPromiseActor> multi_promise_;
|
2018-12-31 20:04:05 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
} // namespace td
|