Asynchronously destroy some big data storages.

This commit is contained in:
levlam 2022-07-20 13:40:14 +03:00
parent ac8af37872
commit 0f87447ffc
26 changed files with 210 additions and 13 deletions

View File

@ -139,6 +139,10 @@ AnimationsManager::AnimationsManager(Td *td, ActorShared<> parent) : td_(td), pa
next_saved_animations_load_time_ = Time::now();
}
AnimationsManager::~AnimationsManager() {
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), animations_);
}
void AnimationsManager::tear_down() {
parent_.reset();
}

View File

@ -29,6 +29,11 @@ class Td;
class AnimationsManager final : public Actor {
public:
AnimationsManager(Td *td, ActorShared<> parent);
AnimationsManager(const AnimationsManager &) = delete;
AnimationsManager &operator=(const AnimationsManager &) = delete;
AnimationsManager(AnimationsManager &&) = delete;
AnimationsManager &operator=(AnimationsManager &&) = delete;
~AnimationsManager() final;
int32 get_animation_duration(FileId file_id) const;

View File

@ -24,6 +24,10 @@ namespace td {
AudiosManager::AudiosManager(Td *td) : td_(td) {
}
AudiosManager::~AudiosManager() {
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), audios_);
}
int32 AudiosManager::get_audio_duration(FileId file_id) const {
auto it = audios_.find(file_id);
if (it == audios_.end()) {

View File

@ -23,6 +23,11 @@ class Td;
class AudiosManager {
public:
explicit AudiosManager(Td *td);
AudiosManager(const AudiosManager &) = delete;
AudiosManager &operator=(const AudiosManager &) = delete;
AudiosManager(AudiosManager &&) = delete;
AudiosManager &operator=(AudiosManager &&) = delete;
~AudiosManager();
int32 get_audio_duration(FileId file_id) const;

View File

@ -3397,7 +3397,45 @@ ContactsManager::ContactsManager(Td *td, ActorShared<> parent) : td_(td), parent
channel_participant_cache_timeout_.set_callback_data(static_cast<void *>(this));
}
ContactsManager::~ContactsManager() = default;
ContactsManager::~ContactsManager() {
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), users_);
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), users_full_);
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), user_photos_);
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), unknown_users_);
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), pending_user_photos_);
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), user_profile_photo_file_source_ids_);
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), my_photo_file_id_);
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), chats_);
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), chats_full_);
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), unknown_chats_);
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), chat_full_file_source_ids_);
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), min_channels_);
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), channels_);
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), channels_full_);
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), unknown_channels_);
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), invalidated_channels_full_);
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), channel_full_file_source_ids_);
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), secret_chats_);
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), unknown_secret_chats_);
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), secret_chats_with_user_);
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), invite_link_infos_);
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), dialog_access_by_invite_link_);
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), loaded_from_database_users_);
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), unavailable_user_fulls_);
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), loaded_from_database_chats_);
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), unavailable_chat_fulls_);
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), loaded_from_database_channels_);
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), unavailable_channel_fulls_);
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), loaded_from_database_secret_chats_);
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), dialog_administrators_);
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), cached_channel_participants_);
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), resolved_phone_numbers_);
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), channel_participants_);
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), all_imported_contacts_);
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), linked_channel_ids_);
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), restricted_user_ids_);
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), restricted_channel_ids_);
}
void ContactsManager::tear_down() {
parent_.reset();

View File

@ -48,6 +48,10 @@ namespace td {
DocumentsManager::DocumentsManager(Td *td) : td_(td) {
}
DocumentsManager::~DocumentsManager() {
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), documents_);
}
tl_object_ptr<td_api::document> DocumentsManager::get_document_object(FileId file_id,
PhotoFormat thumbnail_format) const {
if (!file_id.is_valid()) {

View File

@ -31,6 +31,11 @@ class Td;
class DocumentsManager {
public:
explicit DocumentsManager(Td *td);
DocumentsManager(const DocumentsManager &) = delete;
DocumentsManager &operator=(const DocumentsManager &) = delete;
DocumentsManager(DocumentsManager &&) = delete;
DocumentsManager &operator=(DocumentsManager &&) = delete;
~DocumentsManager();
class RemoteDocument {
public:

View File

@ -32,6 +32,10 @@ namespace td {
int VERBOSITY_NAME(file_references) = VERBOSITY_NAME(INFO);
FileReferenceManager::~FileReferenceManager() {
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), file_sources_);
}
bool FileReferenceManager::is_file_reference_error(const Status &error) {
return error.is_error() && error.code() == 400 && begins_with(error.message(), "FILE_REFERENCE_");
}

View File

@ -35,6 +35,13 @@ extern int VERBOSITY_NAME(file_references);
class FileReferenceManager final : public Actor {
public:
FileReferenceManager() = default;
FileReferenceManager(const FileReferenceManager &) = delete;
FileReferenceManager &operator=(const FileReferenceManager &) = delete;
FileReferenceManager(FileReferenceManager &&) = delete;
FileReferenceManager &operator=(FileReferenceManager &&) = delete;
~FileReferenceManager() final;
static bool is_file_reference_error(const Status &error);
static size_t get_file_reference_error_pos(const Status &error);

View File

@ -5754,12 +5754,6 @@ void MessagesManager::save_calls_db_state() {
G()->td_db()->get_sqlite_pmc()->set("calls_db_state", log_event_store(calls_db_state_).as_slice().str(), Auto());
}
MessagesManager::Dialog::~Dialog() {
if (!G()->close_flag()) {
LOG(ERROR) << "Destroy " << dialog_id;
}
}
MessagesManager::MessagesManager(Td *td, ActorShared<> parent)
: recently_found_dialogs_{td, "recently_found", MAX_RECENT_DIALOGS}
, recently_opened_dialogs_{td, "recently_opened", MAX_RECENT_DIALOGS}
@ -5814,7 +5808,36 @@ MessagesManager::MessagesManager(Td *td, ActorShared<> parent)
update_viewed_messages_timeout_.set_callback_data(static_cast<void *>(this));
}
MessagesManager::~MessagesManager() = default;
MessagesManager::~MessagesManager() {
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), ttl_nodes_);
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), ttl_heap_);
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), being_sent_messages_);
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), update_message_ids_);
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), update_scheduled_message_ids_);
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), message_id_to_dialog_id_);
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), last_clear_history_message_id_to_dialog_id_);
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), dialogs_);
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), postponed_chat_read_inbox_updates_);
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), found_public_dialogs_);
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), found_on_server_dialogs_);
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), found_common_dialogs_);
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), message_embedding_codes_[0]);
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), message_embedding_codes_[1]);
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), replied_by_media_timestamp_messages_);
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), notification_group_id_to_dialog_id_);
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), active_get_channel_differencies_);
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), get_channel_difference_to_log_event_id_);
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), channel_get_difference_retry_timeouts_);
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), is_channel_difference_finished_);
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), resolved_usernames_);
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), inaccessible_resolved_usernames_);
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), dialog_bot_command_message_ids_);
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), full_message_id_to_file_source_id_);
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), last_outgoing_forwarded_message_date_);
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), dialog_viewed_messages_);
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), dialog_online_member_counts_);
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), previous_repaired_read_inbox_max_message_id_);
}
void MessagesManager::on_channel_get_difference_timeout_callback(void *messages_manager_ptr, int64 dialog_id_int) {
if (G()->close_flag()) {

View File

@ -1431,7 +1431,7 @@ class MessagesManager final : public Actor {
Dialog &operator=(const Dialog &) = delete;
Dialog(Dialog &&other) = delete;
Dialog &operator=(Dialog &&other) = delete;
~Dialog();
~Dialog() = default;
template <class StorerT>
void store(StorerT &storer) const;

View File

@ -265,7 +265,13 @@ void PollManager::tear_down() {
parent_.reset();
}
PollManager::~PollManager() = default;
PollManager::~PollManager() {
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), polls_);
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), server_poll_messages_);
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), other_poll_messages_);
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), poll_voters_);
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), loaded_from_database_polls_);
}
void PollManager::on_update_poll_timeout_callback(void *poll_manager_ptr, int64 poll_id_int) {
if (G()->close_flag()) {

View File

@ -30,7 +30,7 @@ class SecretChatsManager final : public Actor {
public:
explicit SecretChatsManager(ActorShared<> parent);
// proxy query to corrensponding SecretChatActor
// proxy query to corresponding SecretChatActor
void on_update_chat(tl_object_ptr<telegram_api::updateEncryption> update);
void on_new_message(tl_object_ptr<telegram_api::EncryptedMessage> &&message_ptr, Promise<Unit> &&promise);

View File

@ -1304,6 +1304,21 @@ StickersManager::StickersManager(Td *td, ActorShared<> parent) : td_(td), parent
next_update_animated_emoji_clicked_time_ = Time::now();
}
StickersManager::~StickersManager() {
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), stickers_);
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), sticker_sets_);
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), short_name_to_sticker_set_id_);
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), attached_sticker_sets_);
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), found_stickers_);
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), found_sticker_sets_);
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), emoji_language_codes_);
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), emoji_language_code_versions_);
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), emoji_language_code_last_difference_times_);
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), reloaded_emoji_keywords_);
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), dice_messages_);
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), emoji_messages_);
}
void StickersManager::start_up() {
init();
}

View File

@ -50,6 +50,11 @@ class StickersManager final : public Actor {
static vector<int64> convert_sticker_set_ids(const vector<StickerSetId> &sticker_set_ids);
StickersManager(Td *td, ActorShared<> parent);
StickersManager(const StickersManager &) = delete;
StickersManager &operator=(const StickersManager &) = delete;
StickersManager(StickersManager &&) = delete;
StickersManager &operator=(StickersManager &&) = delete;
~StickersManager() final;
void init();

View File

@ -22,6 +22,10 @@ namespace td {
VideoNotesManager::VideoNotesManager(Td *td) : td_(td) {
}
VideoNotesManager::~VideoNotesManager() {
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), video_notes_);
}
int32 VideoNotesManager::get_video_note_duration(FileId file_id) const {
auto it = video_notes_.find(file_id);
CHECK(it != video_notes_.end());

View File

@ -24,6 +24,11 @@ class Td;
class VideoNotesManager {
public:
explicit VideoNotesManager(Td *td);
VideoNotesManager(const VideoNotesManager &) = delete;
VideoNotesManager &operator=(const VideoNotesManager &) = delete;
VideoNotesManager(VideoNotesManager &&) = delete;
VideoNotesManager &operator=(VideoNotesManager &&) = delete;
~VideoNotesManager();
int32 get_video_note_duration(FileId file_id) const;

View File

@ -23,6 +23,10 @@ namespace td {
VideosManager::VideosManager(Td *td) : td_(td) {
}
VideosManager::~VideosManager() {
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), videos_);
}
int32 VideosManager::get_video_duration(FileId file_id) const {
auto it = videos_.find(file_id);
CHECK(it != videos_.end());

View File

@ -24,6 +24,11 @@ class Td;
class VideosManager {
public:
explicit VideosManager(Td *td);
VideosManager(const VideosManager &) = delete;
VideosManager &operator=(const VideosManager &) = delete;
VideosManager(VideosManager &&) = delete;
VideosManager &operator=(VideosManager &&) = delete;
~VideosManager();
int32 get_video_duration(FileId file_id) const;

View File

@ -100,6 +100,12 @@ VoiceNotesManager::VoiceNotesManager(Td *td, ActorShared<> parent) : td_(td), pa
voice_note_transcription_timeout_.set_callback_data(static_cast<void *>(this));
}
VoiceNotesManager::~VoiceNotesManager() {
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), voice_notes_);
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), voice_note_messages_);
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), message_voice_notes_);
}
void VoiceNotesManager::tear_down() {
parent_.reset();
}

View File

@ -28,6 +28,11 @@ class Td;
class VoiceNotesManager final : public Actor {
public:
VoiceNotesManager(Td *td, ActorShared<> parent);
VoiceNotesManager(const VoiceNotesManager &) = delete;
VoiceNotesManager &operator=(const VoiceNotesManager &) = delete;
VoiceNotesManager(VoiceNotesManager &&) = delete;
VoiceNotesManager &operator=(VoiceNotesManager &&) = delete;
~VoiceNotesManager() final;
int32 get_voice_note_duration(FileId file_id) const;

View File

@ -417,7 +417,13 @@ void WebPagesManager::tear_down() {
LOG(DEBUG) << "Have " << web_pages_.size() << " web pages to free";
}
WebPagesManager::~WebPagesManager() = default;
WebPagesManager::~WebPagesManager() {
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), web_pages_);
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), web_page_messages_);
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), got_web_page_previews_);
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), url_to_web_page_id_);
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), url_to_file_source_id_);
}
WebPageId WebPagesManager::on_get_web_page(tl_object_ptr<telegram_api::WebPage> &&web_page_ptr,
DialogId owner_dialog_id) {

View File

@ -840,6 +840,14 @@ void FileManager::init_actor() {
}
FileManager::~FileManager() {
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), remote_location_info_);
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), file_hash_to_file_id_);
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), local_location_to_file_id_);
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), generate_location_to_file_id_);
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), pmc_id_to_file_node_id_);
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), file_id_info_);
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), empty_file_ids_);
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), file_nodes_);
}
string FileManager::fix_file_extension(Slice file_name, Slice file_type, Slice file_extension) {

View File

@ -102,6 +102,9 @@ class Scheduler {
void run_on_scheduler(int32 sched_id, Promise<Unit> action); // TODO Action
template <class T>
void destroy_on_scheduler(int32 sched_id, T &value);
template <ActorSendType send_type, class EventT>
void send_lambda(ActorRef actor_ref, EventT &&lambda);

View File

@ -161,7 +161,7 @@ void Scheduler::flush_mailbox(ActorInfo *actor_info, const RunFuncT &run_func, c
mailbox.erase(mailbox.begin(), mailbox.begin() + i);
}
inline void Scheduler::send_to_scheduler(int32 sched_id, const ActorId<> &actor_id, Event &&event) {
inline void Scheduler::send_to_scheduler(int32 sched_id, const ActorId<Actor> &actor_id, Event &&event) {
if (sched_id == sched_id_) {
ActorInfo *actor_info = actor_id.get_actor_info();
pending_events_[actor_info].push_back(std::move(event));
@ -170,6 +170,28 @@ inline void Scheduler::send_to_scheduler(int32 sched_id, const ActorId<> &actor_
}
}
template <class T>
inline void Scheduler::destroy_on_scheduler(int32 sched_id, T &value) {
if (sched_id < 0 || sched_id_ == sched_id || value.empty()) {
return;
}
auto empty_context = std::make_shared<ActorContext>();
empty_context->this_ptr_ = empty_context;
ActorContext *current_context = context_;
context_ = empty_context.get();
const char *current_tag = LOG_TAG;
LOG_TAG = nullptr;
run_on_scheduler(sched_id, PromiseCreator::lambda([value = std::move(value)](Unit) {
// destroy value
}));
context_ = current_context;
LOG_TAG = current_tag;
}
inline void Scheduler::before_tail_send(const ActorId<> &actor_id) {
// TODO
}

View File

@ -42,6 +42,10 @@ class Enumerator {
return arr_.size();
}
bool empty() const {
return size() == 0;
}
private:
std::map<ValueT, int32> map_;
std::vector<const ValueT *> arr_;