diff --git a/td/telegram/Td.cpp b/td/telegram/Td.cpp
index 262e0ecbb..369e4694d 100644
--- a/td/telegram/Td.cpp
+++ b/td/telegram/Td.cpp
@@ -3995,110 +3995,7 @@ Status Td::init(DbKey key) {
VLOG(td_init) << "Successfully inited database";
G()->init(parameters_, actor_id(this), r_td_db.move_as_ok()).ensure();
- // Init all managers and actors
- VLOG(td_init) << "Create StateManager";
- class StateManagerCallback : public StateManager::Callback {
- public:
- explicit StateManagerCallback(ActorShared
td) : td_(std::move(td)) {
- }
- bool on_state(StateManager::State state) override {
- send_closure(td_, &Td::on_connection_state_changed, state);
- return td_.is_alive();
- }
-
- private:
- ActorShared | td_;
- };
- state_manager_ = create_actor("State manager");
- send_closure(state_manager_, &StateManager::add_callback, make_unique(create_reference()));
- G()->set_state_manager(state_manager_.get());
- connection_state_ = StateManager::State::Empty;
-
- VLOG(td_init) << "Create ConfigShared";
- G()->set_shared_config(td::make_unique(G()->td_db()->get_config_pmc_shared()));
-
- if (G()->shared_config().have_option("language_database_path")) {
- G()->shared_config().set_option_string("language_pack_database_path",
- G()->shared_config().get_option_string("language_database_path"));
- G()->shared_config().set_option_empty("language_database_path");
- }
- if (G()->shared_config().have_option("language_pack")) {
- G()->shared_config().set_option_string("localization_target",
- G()->shared_config().get_option_string("language_pack"));
- G()->shared_config().set_option_empty("language_pack");
- }
- if (G()->shared_config().have_option("language_code")) {
- G()->shared_config().set_option_string("language_pack_id", G()->shared_config().get_option_string("language_code"));
- G()->shared_config().set_option_empty("language_code");
- }
- if (!G()->shared_config().have_option("message_text_length_max")) {
- G()->shared_config().set_option_integer("message_text_length_max", 4096);
- }
- if (!G()->shared_config().have_option("message_caption_length_max")) {
- G()->shared_config().set_option_integer("message_caption_length_max", 1024);
- }
-
- VLOG(td_init) << "Create ConnectionCreator";
- {
- auto connection_creator = create_actor("ConnectionCreator", create_reference());
- auto net_stats_manager = create_actor("NetStatsManager", create_reference());
-
- // How else could I let two actor know about each other, without quite complex async logic?
- auto net_stats_manager_ptr = net_stats_manager->get_actor_unsafe();
- net_stats_manager_ptr->init();
- connection_creator->get_actor_unsafe()->set_net_stats_callback(net_stats_manager_ptr->get_common_stats_callback(),
- net_stats_manager_ptr->get_media_stats_callback());
- G()->set_net_stats_file_callbacks(net_stats_manager_ptr->get_file_stats_callbacks());
-
- G()->set_connection_creator(std::move(connection_creator));
- net_stats_manager_ = std::move(net_stats_manager);
-
- complete_pending_preauthentication_requests([](int32 id) {
- switch (id) {
- case td_api::setNetworkType::ID:
- case td_api::getNetworkStatistics::ID:
- case td_api::addNetworkStatistics::ID:
- case td_api::resetNetworkStatistics::ID:
- case td_api::addProxy::ID:
- case td_api::editProxy::ID:
- case td_api::enableProxy::ID:
- case td_api::disableProxy::ID:
- case td_api::removeProxy::ID:
- case td_api::getProxies::ID:
- case td_api::getProxyLink::ID:
- return true;
- default:
- return false;
- }
- });
- }
-
- VLOG(td_init) << "Create TempAuthKeyWatchdog";
- auto temp_auth_key_watchdog = create_actor("TempAuthKeyWatchdog");
- G()->set_temp_auth_key_watchdog(std::move(temp_auth_key_watchdog));
-
- VLOG(td_init) << "Create ConfigManager";
- config_manager_ = create_actor("ConfigManager", create_reference());
- G()->set_config_manager(config_manager_.get());
-
- VLOG(td_init) << "Set ConfigShared callback";
- class ConfigSharedCallback : public ConfigShared::Callback {
- public:
- void on_option_updated(const string &name, const string &value) const override {
- send_closure(G()->td(), &Td::on_config_option_updated, name);
- }
- ~ConfigSharedCallback() override {
- LOG(INFO) << "Destroy ConfigSharedCallback";
- }
- };
- // we need to set ConfigShared callback before td_api::getOption requests are processed for consistency
- // TODO currently they will be inconsistent anyway, because td_api::getOption returns current value,
- // but in td_api::updateOption there will be a newer value, obtained at the time of update creation
- // so, there can be even two succesive updateOption with the same value
- // we need to process td_api::getOption along with td_api::setOption for consistency
- // we need to process td_api::setOption before managers and MTProto header are created,
- // because their initialiation may be affected by the options
- G()->shared_config().set_callback(make_unique());
+ init_options_and_network();
complete_pending_preauthentication_requests([](int32 id) {
switch (id) {
@@ -4129,126 +4026,13 @@ Status Td::init(DbKey key) {
auth_manager_ = td::make_unique(parameters_.api_id, parameters_.api_hash, create_reference());
auth_manager_actor_ = register_actor("AuthManager", auth_manager_.get());
- VLOG(td_init) << "Create FileManager";
- download_file_callback_ = std::make_shared();
- upload_file_callback_ = std::make_shared();
+ init_file_manager();
- class FileManagerContext : public FileManager::Context {
- public:
- explicit FileManagerContext(Td *td) : td_(td) {
- }
+ init_managers();
- void on_new_file(int64 size, int32 cnt) final {
- send_closure(G()->storage_manager(), &StorageManager::on_new_file, size, cnt);
- }
-
- void on_file_updated(FileId file_id) final {
- send_closure(G()->td(), &Td::send_update,
- make_tl_object(td_->file_manager_->get_file_object(file_id)));
- }
-
- bool add_file_source(FileId file_id, FileSourceId file_source_id) final {
- return td_->file_reference_manager_->add_file_source(file_id, file_source_id);
- }
-
- FileSourceId get_wallpapers_file_source_id() final {
- return td_->wallpaper_manager_->get_wallpapers_file_source_id();
- }
-
- bool remove_file_source(FileId file_id, FileSourceId file_source_id) final {
- return td_->file_reference_manager_->remove_file_source(file_id, file_source_id);
- }
-
- void on_merge_files(FileId to_file_id, FileId from_file_id) final {
- td_->file_reference_manager_->merge(to_file_id, from_file_id);
- }
-
- vector get_some_file_sources(FileId file_id) final {
- return td_->file_reference_manager_->get_some_file_sources(file_id);
- }
-
- void repair_file_reference(FileId file_id, Promise promise) final {
- send_closure(G()->file_reference_manager(), &FileReferenceManager::repair_file_reference, file_id,
- std::move(promise));
- }
-
- ActorShared<> create_reference() final {
- return td_->create_reference();
- }
-
- private:
- Td *td_;
- };
-
- file_manager_ = make_unique(make_unique(this));
- file_manager_actor_ = register_actor("FileManager", file_manager_.get());
- file_manager_->init_actor();
- G()->set_file_manager(file_manager_actor_.get());
-
- file_reference_manager_ = make_unique();
- file_reference_manager_actor_ = register_actor("FileReferenceManager", file_reference_manager_.get());
- G()->set_file_reference_manager(file_reference_manager_actor_.get());
-
- VLOG(td_init) << "Create Managers";
- audios_manager_ = make_unique(this);
- callback_queries_manager_ = make_unique(this);
- documents_manager_ = make_unique(this);
- video_notes_manager_ = make_unique(this);
- videos_manager_ = make_unique(this);
- voice_notes_manager_ = make_unique(this);
-
- animations_manager_ = make_unique(this, create_reference());
- animations_manager_actor_ = register_actor("AnimationsManager", animations_manager_.get());
- G()->set_animations_manager(animations_manager_actor_.get());
- contacts_manager_ = make_unique(this, create_reference());
- contacts_manager_actor_ = register_actor("ContactsManager", contacts_manager_.get());
- G()->set_contacts_manager(contacts_manager_actor_.get());
- inline_queries_manager_ = make_unique(this, create_reference());
- inline_queries_manager_actor_ = register_actor("InlineQueriesManager", inline_queries_manager_.get());
- messages_manager_ = make_unique(this, create_reference());
- messages_manager_actor_ = register_actor("MessagesManager", messages_manager_.get());
- G()->set_messages_manager(messages_manager_actor_.get());
- notification_manager_ = make_unique(this, create_reference());
- notification_manager_actor_ = register_actor("NotificationManager", notification_manager_.get());
- poll_manager_ = make_unique(this, create_reference());
- poll_manager_actor_ = register_actor("PollManager", poll_manager_.get());
- G()->set_notification_manager(notification_manager_actor_.get());
- stickers_manager_ = make_unique(this, create_reference());
- stickers_manager_actor_ = register_actor("StickersManager", stickers_manager_.get());
- G()->set_stickers_manager(stickers_manager_actor_.get());
- updates_manager_ = make_unique(this, create_reference());
- updates_manager_actor_ = register_actor("UpdatesManager", updates_manager_.get());
- G()->set_updates_manager(updates_manager_actor_.get());
- wallpaper_manager_ = make_unique(this, create_reference());
- wallpaper_manager_actor_ = register_actor("WallpaperManager", wallpaper_manager_.get());
- G()->set_wallpaper_manager(wallpaper_manager_actor_.get());
- web_pages_manager_ = make_unique(this, create_reference());
- web_pages_manager_actor_ = register_actor("WebPagesManager", web_pages_manager_.get());
- G()->set_web_pages_manager(web_pages_manager_actor_.get());
-
- call_manager_ = create_actor("CallManager", create_reference());
- G()->set_call_manager(call_manager_.get());
- change_phone_number_manager_ = create_actor(
- "ChangePhoneNumberManager", PhoneNumberManager::Type::ChangePhone, create_reference());
- confirm_phone_number_manager_ = create_actor(
- "ConfirmPhoneNumberManager", PhoneNumberManager::Type::ConfirmPhone, create_reference());
- device_token_manager_ = create_actor("DeviceTokenManager", create_reference());
- hashtag_hints_ = create_actor("HashtagHints", "text", create_reference());
- language_pack_manager_ = create_actor("LanguagePackManager", create_reference());
- G()->set_language_pack_manager(language_pack_manager_.get());
- password_manager_ = create_actor("PasswordManager", create_reference());
- G()->set_password_manager(password_manager_.get());
- privacy_manager_ = create_actor("PrivacyManager", create_reference());
- secret_chats_manager_ = create_actor("SecretChatsManager", create_reference());
- G()->set_secret_chats_manager(secret_chats_manager_.get());
- secure_manager_ = create_actor("SecureManager", create_reference());
storage_manager_ = create_actor("StorageManager", create_reference(),
min(current_scheduler_id + 2, scheduler_count - 1));
G()->set_storage_manager(storage_manager_.get());
- top_dialog_manager_ = create_actor("TopDialogManager", create_reference());
- G()->set_top_dialog_manager(top_dialog_manager_.get());
- verify_phone_number_manager_ = create_actor(
- "VerifyPhoneNumberManager", PhoneNumberManager::Type::VerifyPhone, create_reference());
VLOG(td_init) << "Send binlog events";
for (auto &event : events.user_events) {
@@ -4331,6 +4115,236 @@ Status Td::init(DbKey key) {
return Status::OK();
}
+void Td::init_options_and_network() {
+ VLOG(td_init) << "Create StateManager";
+ class StateManagerCallback : public StateManager::Callback {
+ public:
+ explicit StateManagerCallback(ActorShared td) : td_(std::move(td)) {
+ }
+ bool on_state(StateManager::State state) override {
+ send_closure(td_, &Td::on_connection_state_changed, state);
+ return td_.is_alive();
+ }
+
+ private:
+ ActorShared | td_;
+ };
+ state_manager_ = create_actor("State manager");
+ send_closure(state_manager_, &StateManager::add_callback, make_unique(create_reference()));
+ G()->set_state_manager(state_manager_.get());
+ connection_state_ = StateManager::State::Empty;
+
+ VLOG(td_init) << "Create ConfigShared";
+ G()->set_shared_config(td::make_unique(G()->td_db()->get_config_pmc_shared()));
+
+ if (G()->shared_config().have_option("language_database_path")) {
+ G()->shared_config().set_option_string("language_pack_database_path",
+ G()->shared_config().get_option_string("language_database_path"));
+ G()->shared_config().set_option_empty("language_database_path");
+ }
+ if (G()->shared_config().have_option("language_pack")) {
+ G()->shared_config().set_option_string("localization_target",
+ G()->shared_config().get_option_string("language_pack"));
+ G()->shared_config().set_option_empty("language_pack");
+ }
+ if (G()->shared_config().have_option("language_code")) {
+ G()->shared_config().set_option_string("language_pack_id", G()->shared_config().get_option_string("language_code"));
+ G()->shared_config().set_option_empty("language_code");
+ }
+ if (!G()->shared_config().have_option("message_text_length_max")) {
+ G()->shared_config().set_option_integer("message_text_length_max", 4096);
+ }
+ if (!G()->shared_config().have_option("message_caption_length_max")) {
+ G()->shared_config().set_option_integer("message_caption_length_max", 1024);
+ }
+
+ init_connection_creator();
+
+ VLOG(td_init) << "Create TempAuthKeyWatchdog";
+ auto temp_auth_key_watchdog = create_actor("TempAuthKeyWatchdog");
+ G()->set_temp_auth_key_watchdog(std::move(temp_auth_key_watchdog));
+
+ VLOG(td_init) << "Create ConfigManager";
+ config_manager_ = create_actor("ConfigManager", create_reference());
+ G()->set_config_manager(config_manager_.get());
+
+ VLOG(td_init) << "Set ConfigShared callback";
+ class ConfigSharedCallback : public ConfigShared::Callback {
+ public:
+ void on_option_updated(const string &name, const string &value) const override {
+ send_closure(G()->td(), &Td::on_config_option_updated, name);
+ }
+ ~ConfigSharedCallback() override {
+ LOG(INFO) << "Destroy ConfigSharedCallback";
+ }
+ };
+ // we need to set ConfigShared callback before td_api::getOption requests are processed for consistency
+ // TODO currently they will be inconsistent anyway, because td_api::getOption returns current value,
+ // but in td_api::updateOption there will be a newer value, obtained at the time of update creation
+ // so, there can be even two succesive updateOption with the same value
+ // we need to process td_api::getOption along with td_api::setOption for consistency
+ // we need to process td_api::setOption before managers and MTProto header are created,
+ // because their initialiation may be affected by the options
+ G()->shared_config().set_callback(make_unique());
+}
+
+void Td::init_connection_creator() {
+ VLOG(td_init) << "Create ConnectionCreator";
+ auto connection_creator = create_actor("ConnectionCreator", create_reference());
+ auto net_stats_manager = create_actor("NetStatsManager", create_reference());
+
+ // How else could I let two actor know about each other, without quite complex async logic?
+ auto net_stats_manager_ptr = net_stats_manager->get_actor_unsafe();
+ net_stats_manager_ptr->init();
+ connection_creator->get_actor_unsafe()->set_net_stats_callback(net_stats_manager_ptr->get_common_stats_callback(),
+ net_stats_manager_ptr->get_media_stats_callback());
+ G()->set_net_stats_file_callbacks(net_stats_manager_ptr->get_file_stats_callbacks());
+
+ G()->set_connection_creator(std::move(connection_creator));
+ net_stats_manager_ = std::move(net_stats_manager);
+
+ complete_pending_preauthentication_requests([](int32 id) {
+ switch (id) {
+ case td_api::setNetworkType::ID:
+ case td_api::getNetworkStatistics::ID:
+ case td_api::addNetworkStatistics::ID:
+ case td_api::resetNetworkStatistics::ID:
+ case td_api::addProxy::ID:
+ case td_api::editProxy::ID:
+ case td_api::enableProxy::ID:
+ case td_api::disableProxy::ID:
+ case td_api::removeProxy::ID:
+ case td_api::getProxies::ID:
+ case td_api::getProxyLink::ID:
+ return true;
+ default:
+ return false;
+ }
+ });
+}
+
+void Td::init_file_manager() {
+ VLOG(td_init) << "Create FileManager";
+ download_file_callback_ = std::make_shared();
+ upload_file_callback_ = std::make_shared();
+
+ class FileManagerContext : public FileManager::Context {
+ public:
+ explicit FileManagerContext(Td *td) : td_(td) {
+ }
+
+ void on_new_file(int64 size, int32 cnt) final {
+ send_closure(G()->storage_manager(), &StorageManager::on_new_file, size, cnt);
+ }
+
+ void on_file_updated(FileId file_id) final {
+ send_closure(G()->td(), &Td::send_update,
+ make_tl_object(td_->file_manager_->get_file_object(file_id)));
+ }
+
+ bool add_file_source(FileId file_id, FileSourceId file_source_id) final {
+ return td_->file_reference_manager_->add_file_source(file_id, file_source_id);
+ }
+
+ FileSourceId get_wallpapers_file_source_id() final {
+ return td_->wallpaper_manager_->get_wallpapers_file_source_id();
+ }
+
+ bool remove_file_source(FileId file_id, FileSourceId file_source_id) final {
+ return td_->file_reference_manager_->remove_file_source(file_id, file_source_id);
+ }
+
+ void on_merge_files(FileId to_file_id, FileId from_file_id) final {
+ td_->file_reference_manager_->merge(to_file_id, from_file_id);
+ }
+
+ vector get_some_file_sources(FileId file_id) final {
+ return td_->file_reference_manager_->get_some_file_sources(file_id);
+ }
+
+ void repair_file_reference(FileId file_id, Promise promise) final {
+ send_closure(G()->file_reference_manager(), &FileReferenceManager::repair_file_reference, file_id,
+ std::move(promise));
+ }
+
+ ActorShared<> create_reference() final {
+ return td_->create_reference();
+ }
+
+ private:
+ Td *td_;
+ };
+
+ file_manager_ = make_unique(make_unique(this));
+ file_manager_actor_ = register_actor("FileManager", file_manager_.get());
+ file_manager_->init_actor();
+ G()->set_file_manager(file_manager_actor_.get());
+
+ file_reference_manager_ = make_unique();
+ file_reference_manager_actor_ = register_actor("FileReferenceManager", file_reference_manager_.get());
+ G()->set_file_reference_manager(file_reference_manager_actor_.get());
+}
+
+void Td::init_managers() {
+ VLOG(td_init) << "Create Managers";
+ audios_manager_ = make_unique(this);
+ callback_queries_manager_ = make_unique(this);
+ documents_manager_ = make_unique(this);
+ video_notes_manager_ = make_unique(this);
+ videos_manager_ = make_unique(this);
+ voice_notes_manager_ = make_unique(this);
+
+ animations_manager_ = make_unique(this, create_reference());
+ animations_manager_actor_ = register_actor("AnimationsManager", animations_manager_.get());
+ G()->set_animations_manager(animations_manager_actor_.get());
+ contacts_manager_ = make_unique(this, create_reference());
+ contacts_manager_actor_ = register_actor("ContactsManager", contacts_manager_.get());
+ G()->set_contacts_manager(contacts_manager_actor_.get());
+ inline_queries_manager_ = make_unique(this, create_reference());
+ inline_queries_manager_actor_ = register_actor("InlineQueriesManager", inline_queries_manager_.get());
+ messages_manager_ = make_unique(this, create_reference());
+ messages_manager_actor_ = register_actor("MessagesManager", messages_manager_.get());
+ G()->set_messages_manager(messages_manager_actor_.get());
+ notification_manager_ = make_unique(this, create_reference());
+ notification_manager_actor_ = register_actor("NotificationManager", notification_manager_.get());
+ poll_manager_ = make_unique(this, create_reference());
+ poll_manager_actor_ = register_actor("PollManager", poll_manager_.get());
+ G()->set_notification_manager(notification_manager_actor_.get());
+ stickers_manager_ = make_unique(this, create_reference());
+ stickers_manager_actor_ = register_actor("StickersManager", stickers_manager_.get());
+ G()->set_stickers_manager(stickers_manager_actor_.get());
+ updates_manager_ = make_unique(this, create_reference());
+ updates_manager_actor_ = register_actor("UpdatesManager", updates_manager_.get());
+ G()->set_updates_manager(updates_manager_actor_.get());
+ wallpaper_manager_ = make_unique(this, create_reference());
+ wallpaper_manager_actor_ = register_actor("WallpaperManager", wallpaper_manager_.get());
+ G()->set_wallpaper_manager(wallpaper_manager_actor_.get());
+ web_pages_manager_ = make_unique(this, create_reference());
+ web_pages_manager_actor_ = register_actor("WebPagesManager", web_pages_manager_.get());
+ G()->set_web_pages_manager(web_pages_manager_actor_.get());
+
+ call_manager_ = create_actor("CallManager", create_reference());
+ G()->set_call_manager(call_manager_.get());
+ change_phone_number_manager_ = create_actor(
+ "ChangePhoneNumberManager", PhoneNumberManager::Type::ChangePhone, create_reference());
+ confirm_phone_number_manager_ = create_actor(
+ "ConfirmPhoneNumberManager", PhoneNumberManager::Type::ConfirmPhone, create_reference());
+ device_token_manager_ = create_actor("DeviceTokenManager", create_reference());
+ hashtag_hints_ = create_actor("HashtagHints", "text", create_reference());
+ language_pack_manager_ = create_actor("LanguagePackManager", create_reference());
+ G()->set_language_pack_manager(language_pack_manager_.get());
+ password_manager_ = create_actor("PasswordManager", create_reference());
+ G()->set_password_manager(password_manager_.get());
+ privacy_manager_ = create_actor("PrivacyManager", create_reference());
+ secret_chats_manager_ = create_actor("SecretChatsManager", create_reference());
+ G()->set_secret_chats_manager(secret_chats_manager_.get());
+ secure_manager_ = create_actor("SecureManager", create_reference());
+ top_dialog_manager_ = create_actor("TopDialogManager", create_reference());
+ G()->set_top_dialog_manager(top_dialog_manager_.get());
+ verify_phone_number_manager_ = create_actor(
+ "VerifyPhoneNumberManager", PhoneNumberManager::Type::VerifyPhone, create_reference());
+}
+
void Td::send_get_nearest_dc_query(Promise promise) {
create_handler(std::move(promise))->send();
}
diff --git a/td/telegram/Td.h b/td/telegram/Td.h
index aaee22071..a094241f9 100644
--- a/td/telegram/Td.h
+++ b/td/telegram/Td.h
@@ -1039,6 +1039,10 @@ class Td final : public NetQueryCallback {
static DbKey as_db_key(string key);
Status init(DbKey key) TD_WARN_UNUSED_RESULT;
+ void init_options_and_network();
+ void init_connection_creator();
+ void init_file_manager();
+ void init_managers();
void clear();
void close_impl(bool destroy_flag);
static Status fix_parameters(TdParameters ¶meters) TD_WARN_UNUSED_RESULT;
| |