From 4ab14b620aa578a43a902527087701dde69d2cf6 Mon Sep 17 00:00:00 2001 From: levlam Date: Mon, 1 Oct 2018 02:26:06 +0300 Subject: [PATCH] Move RequestActor to RequestActor.h. GitOrigin-RevId: 50b21b9832f0a9871f6c2fc54ab45818b04258b8 --- CMakeLists.txt | 1 + td/telegram/RequestActor.h | 151 +++++++++++++++++++++++++++++++++++++ td/telegram/Td.cpp | 130 +------------------------------ 3 files changed, 153 insertions(+), 129 deletions(-) create mode 100644 td/telegram/RequestActor.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 134831d67..6084bcd12 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -534,6 +534,7 @@ set(TDLIB_SOURCE td/telegram/PrivacyManager.h td/telegram/PtsManager.h td/telegram/ReplyMarkup.h + td/telegram/RequestActor.h td/telegram/SecretChatActor.h td/telegram/SecretChatId.h td/telegram/SecretChatDb.h diff --git a/td/telegram/RequestActor.h b/td/telegram/RequestActor.h new file mode 100644 index 000000000..d4b577f42 --- /dev/null +++ b/td/telegram/RequestActor.h @@ -0,0 +1,151 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2018 +// +// 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" +#include "td/utils/logging.h" +#include "td/utils/Status.h" + +#include + +namespace td { + +class Td; + +template +class RequestActor : public Actor { + public: + RequestActor(ActorShared td_id, uint64 request_id) + : td_id_(std::move(td_id)), td(td_id_.get().get_actor_unsafe()), request_id_(request_id) { + } + + void loop() override { + PromiseActor promise; + FutureActor future; + init_promise_future(&promise, &future); + + do_run(PromiseCreator::from_promise_actor(std::move(promise))); + + if (future.is_ready()) { + if (future.is_error()) { + do_send_error(future.move_as_error()); + } else { + do_set_result(future.move_as_ok()); + do_send_result(); + } + stop(); + } else { + if (--tries_left_ == 0) { + future.close(); + do_send_error(Status::Error(400, "Requested data is unaccessible")); + return stop(); + } + + future.set_event(EventCreator::raw(actor_id(), nullptr)); + future_ = std::move(future); + } + } + + void raw_event(const Event::Raw &event) override { + if (future_.is_error()) { + auto error = future_.move_as_error(); + if (error == Status::Error::Hangup>()) { + // dropping query due to lost authorization or lost promise + // td may be already closed, so we should check is auth_manager_ is empty + bool is_authorized = td->auth_manager_ && td->auth_manager_->is_authorized(); + if (is_authorized) { + LOG(ERROR) << "Promise was lost"; + do_send_error(Status::Error(500, "Query can't be answered due to bug in the TDLib")); + } else { + do_send_error(Status::Error(401, "Unauthorized")); + } + return stop(); + } + + do_send_error(std::move(error)); + stop(); + } else { + do_set_result(future_.move_as_ok()); + loop(); + } + } + + void on_start_migrate(int32 /*sched_id*/) override { + UNREACHABLE(); + } + void on_finish_migrate() override { + UNREACHABLE(); + } + + int get_tries() const { + return tries_left_; + } + + void set_tries(int32 tries) { + tries_left_ = tries; + } + + protected: + ActorShared td_id_; + Td *td; + + void send_result(tl_object_ptr &&result) { + send_closure(td_id_, &Td::send_result, request_id_, std::move(result)); + } + + void send_error(Status &&status) { + LOG(INFO) << "Receive error for query: " << status; + send_closure(td_id_, &Td::send_error, request_id_, std::move(status)); + } + + private: + virtual void do_run(Promise &&promise) = 0; + + virtual void do_send_result() { + send_result(make_tl_object()); + } + + virtual void do_send_error(Status &&status) { + send_error(std::move(status)); + } + + virtual void do_set_result(T &&result) { + CHECK((std::is_same::value)); // all other results should be implicitly handled by overriding this method + } + + void hangup() override { + do_send_error(Status::Error(500, "Request aborted")); + stop(); + } + + friend class RequestOnceActor; + + uint64 request_id_; + int tries_left_ = 2; + FutureActor future_; +}; + +class RequestOnceActor : public RequestActor<> { + public: + RequestOnceActor(ActorShared td_id, uint64 request_id) : RequestActor(std::move(td_id), request_id) { + } + + void loop() override { + if (get_tries() < 2) { + do_send_result(); + stop(); + return; + } + + RequestActor::loop(); + } +}; + +} // namespace td \ No newline at end of file diff --git a/td/telegram/Td.cpp b/td/telegram/Td.cpp index 878644e9c..d7d4d9471 100644 --- a/td/telegram/Td.cpp +++ b/td/telegram/Td.cpp @@ -48,6 +48,7 @@ #include "td/telegram/Payments.h" #include "td/telegram/Photo.h" #include "td/telegram/PrivacyManager.h" +#include "td/telegram/RequestActor.h" #include "td/telegram/SecretChatId.h" #include "td/telegram/SecretChatsManager.h" #include "td/telegram/SecureManager.h" @@ -505,135 +506,6 @@ class GetDeepLinkInfoQuery : public Td::ResultHandler { } }; -template -class RequestActor : public Actor { - public: - RequestActor(ActorShared td_id, uint64 request_id) - : td_id_(std::move(td_id)), td(td_id_.get().get_actor_unsafe()), request_id_(request_id) { - } - - void loop() override { - PromiseActor promise; - FutureActor future; - init_promise_future(&promise, &future); - - do_run(PromiseCreator::from_promise_actor(std::move(promise))); - - if (future.is_ready()) { - if (future.is_error()) { - do_send_error(future.move_as_error()); - } else { - do_set_result(future.move_as_ok()); - do_send_result(); - } - stop(); - } else { - if (--tries_left_ == 0) { - future.close(); - do_send_error(Status::Error(400, "Requested data is unaccessible")); - return stop(); - } - - future.set_event(EventCreator::raw(actor_id(), nullptr)); - future_ = std::move(future); - } - } - - void raw_event(const Event::Raw &event) override { - if (future_.is_error()) { - auto error = future_.move_as_error(); - if (error == Status::Error::Hangup>()) { - // dropping query due to lost authorization or lost promise - // td may be already closed, so we should check is auth_manager_ is empty - bool is_authorized = td->auth_manager_ && td->auth_manager_->is_authorized(); - if (is_authorized) { - LOG(ERROR) << "Promise was lost"; - do_send_error(Status::Error(500, "Query can't be answered due to bug in the TDLib")); - } else { - do_send_error(Status::Error(401, "Unauthorized")); - } - return stop(); - } - - do_send_error(std::move(error)); - stop(); - } else { - do_set_result(future_.move_as_ok()); - loop(); - } - } - - void on_start_migrate(int32 /*sched_id*/) override { - UNREACHABLE(); - } - void on_finish_migrate() override { - UNREACHABLE(); - } - - int get_tries() const { - return tries_left_; - } - - void set_tries(int32 tries) { - tries_left_ = tries; - } - - protected: - ActorShared td_id_; - Td *td; - - void send_result(tl_object_ptr &&result) { - send_closure(td_id_, &Td::send_result, request_id_, std::move(result)); - } - - void send_error(Status &&status) { - LOG(INFO) << "Receive error for query: " << status; - send_closure(td_id_, &Td::send_error, request_id_, std::move(status)); - } - - private: - virtual void do_run(Promise &&promise) = 0; - - virtual void do_send_result() { - send_result(make_tl_object()); - } - - virtual void do_send_error(Status &&status) { - send_error(std::move(status)); - } - - virtual void do_set_result(T &&result) { - CHECK((std::is_same::value)); // all other results should be implicitly handled by overriding this method - } - - void hangup() override { - do_send_error(Status::Error(500, "Request aborted")); - stop(); - } - - friend class RequestOnceActor; - - uint64 request_id_; - int tries_left_ = 2; - FutureActor future_; -}; - -class RequestOnceActor : public RequestActor<> { - public: - RequestOnceActor(ActorShared td_id, uint64 request_id) : RequestActor(std::move(td_id), request_id) { - } - - void loop() override { - if (get_tries() < 2) { - do_send_result(); - stop(); - return; - } - - RequestActor::loop(); - } -}; - /*** Td ***/ /** Td queries **/ class TestQuery : public Td::ResultHandler {