Move RequestActor to RequestActor.h.
GitOrigin-RevId: 50b21b9832f0a9871f6c2fc54ab45818b04258b8
This commit is contained in:
parent
ad81123d60
commit
4ab14b620a
@ -534,6 +534,7 @@ set(TDLIB_SOURCE
|
|||||||
td/telegram/PrivacyManager.h
|
td/telegram/PrivacyManager.h
|
||||||
td/telegram/PtsManager.h
|
td/telegram/PtsManager.h
|
||||||
td/telegram/ReplyMarkup.h
|
td/telegram/ReplyMarkup.h
|
||||||
|
td/telegram/RequestActor.h
|
||||||
td/telegram/SecretChatActor.h
|
td/telegram/SecretChatActor.h
|
||||||
td/telegram/SecretChatId.h
|
td/telegram/SecretChatId.h
|
||||||
td/telegram/SecretChatDb.h
|
td/telegram/SecretChatDb.h
|
||||||
|
151
td/telegram/RequestActor.h
Normal file
151
td/telegram/RequestActor.h
Normal file
@ -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 <type_traits>
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
|
||||||
|
class Td;
|
||||||
|
|
||||||
|
template <class T = Unit>
|
||||||
|
class RequestActor : public Actor {
|
||||||
|
public:
|
||||||
|
RequestActor(ActorShared<Td> 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<T> promise;
|
||||||
|
FutureActor<T> 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<FutureActor<T>::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> td_id_;
|
||||||
|
Td *td;
|
||||||
|
|
||||||
|
void send_result(tl_object_ptr<td_api::Object> &&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<T> &&promise) = 0;
|
||||||
|
|
||||||
|
virtual void do_send_result() {
|
||||||
|
send_result(make_tl_object<td_api::ok>());
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void do_send_error(Status &&status) {
|
||||||
|
send_error(std::move(status));
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void do_set_result(T &&result) {
|
||||||
|
CHECK((std::is_same<T, Unit>::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<T> future_;
|
||||||
|
};
|
||||||
|
|
||||||
|
class RequestOnceActor : public RequestActor<> {
|
||||||
|
public:
|
||||||
|
RequestOnceActor(ActorShared<Td> 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
|
@ -48,6 +48,7 @@
|
|||||||
#include "td/telegram/Payments.h"
|
#include "td/telegram/Payments.h"
|
||||||
#include "td/telegram/Photo.h"
|
#include "td/telegram/Photo.h"
|
||||||
#include "td/telegram/PrivacyManager.h"
|
#include "td/telegram/PrivacyManager.h"
|
||||||
|
#include "td/telegram/RequestActor.h"
|
||||||
#include "td/telegram/SecretChatId.h"
|
#include "td/telegram/SecretChatId.h"
|
||||||
#include "td/telegram/SecretChatsManager.h"
|
#include "td/telegram/SecretChatsManager.h"
|
||||||
#include "td/telegram/SecureManager.h"
|
#include "td/telegram/SecureManager.h"
|
||||||
@ -505,135 +506,6 @@ class GetDeepLinkInfoQuery : public Td::ResultHandler {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class T = Unit>
|
|
||||||
class RequestActor : public Actor {
|
|
||||||
public:
|
|
||||||
RequestActor(ActorShared<Td> 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<T> promise;
|
|
||||||
FutureActor<T> 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<FutureActor<T>::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> td_id_;
|
|
||||||
Td *td;
|
|
||||||
|
|
||||||
void send_result(tl_object_ptr<td_api::Object> &&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<T> &&promise) = 0;
|
|
||||||
|
|
||||||
virtual void do_send_result() {
|
|
||||||
send_result(make_tl_object<td_api::ok>());
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void do_send_error(Status &&status) {
|
|
||||||
send_error(std::move(status));
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void do_set_result(T &&result) {
|
|
||||||
CHECK((std::is_same<T, Unit>::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<T> future_;
|
|
||||||
};
|
|
||||||
|
|
||||||
class RequestOnceActor : public RequestActor<> {
|
|
||||||
public:
|
|
||||||
RequestOnceActor(ActorShared<Td> 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 ***/
|
||||||
/** Td queries **/
|
/** Td queries **/
|
||||||
class TestQuery : public Td::ResultHandler {
|
class TestQuery : public Td::ResultHandler {
|
||||||
|
Loading…
Reference in New Issue
Block a user