From a52bdbf79cf3be1b06f86675d0b2fd9175d227d6 Mon Sep 17 00:00:00 2001 From: levlam Date: Wed, 28 Jun 2023 17:52:33 +0300 Subject: [PATCH] Add LoadDialogExpiringStoriesLogEvent. --- td/generate/scheme/td_api.tl | 2 +- td/telegram/StoryManager.cpp | 74 ++++++++++++++++++++++++++++++--- td/telegram/StoryManager.h | 9 +++- td/telegram/TdDb.cpp | 1 + td/telegram/logevent/LogEvent.h | 1 + 5 files changed, 80 insertions(+), 7 deletions(-) diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index d356ab1f0..68fcc3279 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -4954,7 +4954,7 @@ stories total_count:int32 stories:vector = Stories; storyInfo story_id:int32 date:int32 = StoryInfo; //@description Describes active stories sent by the same sender -//@list Identifier of the story list in which the stories are shown; maybe null if the stories aren't from a current user's contact +//@list Identifier of the story list in which the stories are shown; may be null if the stories aren't from a current user's contact //@story_sender_chat_id Identifier of the sender of the stories //@max_read_story_id Identifier of the last read active story //@stories Basic information about the stories; use getStory to get full information about the stories diff --git a/td/telegram/StoryManager.cpp b/td/telegram/StoryManager.cpp index 55b7061df..fc6c5df93 100644 --- a/td/telegram/StoryManager.cpp +++ b/td/telegram/StoryManager.cpp @@ -971,10 +971,62 @@ void StoryManager::get_dialog_expiring_stories(DialogId owner_dialog_id, td_->create_handler(std::move(query_promise))->send(owner_dialog_id.get_user_id()); } -void StoryManager::load_dialog_expiring_stories(DialogId owner_dialog_id) { +class StoryManager::LoadDialogExpiringStoriesLogEvent { + public: + DialogId dialog_id_; + + template + void store(StorerT &storer) const { + td::store(dialog_id_, storer); + } + + template + void parse(ParserT &parser) { + td::parse(dialog_id_, parser); + } +}; + +uint64 StoryManager::save_load_dialog_expiring_stories_log_event(DialogId owner_dialog_id) { + LoadDialogExpiringStoriesLogEvent log_event{owner_dialog_id}; + return binlog_add(G()->td_db()->get_binlog(), LogEvent::HandlerType::LoadDialogExpiringStories, + get_log_event_storer(log_event)); +} + +void StoryManager::load_dialog_expiring_stories(DialogId owner_dialog_id, uint64 log_event_id) { + if (load_expiring_stories_log_event_ids_.count(owner_dialog_id)) { + if (log_event_id != 0) { + binlog_erase(G()->td_db()->get_binlog(), log_event_id); + } + return; + } + if (log_event_id == 0 && G()->use_message_database()) { + log_event_id = save_load_dialog_expiring_stories_log_event(owner_dialog_id); + } + load_expiring_stories_log_event_ids_[owner_dialog_id] = log_event_id; + // send later to ensure that active stories are inited before sending the request - send_closure_later(actor_id(this), &StoryManager::get_dialog_expiring_stories, owner_dialog_id, - Promise>()); + auto promise = PromiseCreator::lambda( + [actor_id = actor_id(this), owner_dialog_id](Result> &&) { + if (!G()->close_flag()) { + send_closure(actor_id, &StoryManager::on_load_dialog_expiring_stories, owner_dialog_id); + } + }); + send_closure_later(actor_id(this), &StoryManager::get_dialog_expiring_stories, owner_dialog_id, std::move(promise)); +} + +void StoryManager::on_load_dialog_expiring_stories(DialogId owner_dialog_id) { + if (G()->close_flag()) { + return; + } + auto it = load_expiring_stories_log_event_ids_.find(owner_dialog_id); + if (it != load_expiring_stories_log_event_ids_.end()) { + return; + } + auto log_event_id = it->second; + load_expiring_stories_log_event_ids_.erase(it); + if (log_event_id != 0) { + binlog_erase(G()->td_db()->get_binlog(), log_event_id); + } } void StoryManager::on_get_dialog_expiring_stories(DialogId owner_dialog_id, @@ -1197,7 +1249,7 @@ uint64 StoryManager::save_read_stories_on_server_log_event(DialogId dialog_id, S } void StoryManager::read_stories_on_server(DialogId owner_dialog_id, StoryId story_id, uint64 log_event_id) { - if (log_event_id == 0 && G()->use_chat_info_database()) { + if (log_event_id == 0 && G()->use_message_database()) { log_event_id = save_read_stories_on_server_log_event(owner_dialog_id, story_id); } @@ -1638,7 +1690,7 @@ StoryId StoryManager::on_get_new_story(DialogId owner_dialog_id, auto active_stories = get_active_stories(owner_dialog_id); if (active_stories == nullptr) { if (is_subscribed_to_dialog_stories(owner_dialog_id)) { - load_dialog_expiring_stories(owner_dialog_id); + load_dialog_expiring_stories(owner_dialog_id, 0); } } else if (!contains(active_stories->story_ids_, story_id)) { auto story_ids = active_stories->story_ids_; @@ -2508,6 +2560,18 @@ void StoryManager::on_binlog_events(vector &&events) { read_stories_on_server(dialog_id, max_read_story_id, event.id_); break; } + case LogEvent::HandlerType::LoadDialogExpiringStories: { + LoadDialogExpiringStoriesLogEvent log_event; + log_event_parse(log_event, event.get_data()).ensure(); + + auto dialog_id = log_event.dialog_id_; + if (!td_->messages_manager_->have_dialog_force(dialog_id, "LoadDialogExpiringStoriesLogEvent")) { + binlog_erase(G()->td_db()->get_binlog(), event.id_); + break; + } + load_dialog_expiring_stories(dialog_id, event.id_); + break; + } default: LOG(FATAL) << "Unsupported log event type " << event.type_; } diff --git a/td/telegram/StoryManager.h b/td/telegram/StoryManager.h index 349e37de8..9ecefb85a 100644 --- a/td/telegram/StoryManager.h +++ b/td/telegram/StoryManager.h @@ -195,6 +195,7 @@ class StoryManager final : public Actor { class DeleteStoryOnServerLogEvent; class ReadStoriesOnServerLogEvent; + class LoadDialogExpiringStoriesLogEvent; static constexpr int32 OPENED_STORY_POLL_PERIOD = 60; static constexpr int32 VIEWED_STORY_POLL_PERIOD = 300; @@ -268,7 +269,11 @@ class StoryManager final : public Actor { telegram_api::object_ptr &&stories, Promise> &&promise); - void load_dialog_expiring_stories(DialogId owner_dialog_id); + static uint64 save_load_dialog_expiring_stories_log_event(DialogId owner_dialog_id); + + void load_dialog_expiring_stories(DialogId owner_dialog_id, uint64 log_event_id); + + void on_load_dialog_expiring_stories(DialogId owner_dialog_id); vector get_story_file_ids(const Story *story) const; @@ -340,6 +345,8 @@ class StoryManager final : public Actor { WaitFreeHashMap max_read_story_ids_; + FlatHashMap load_expiring_stories_log_event_ids_; + FlatHashMap, StoryFullIdHash> being_edited_stories_; FlatHashMap pending_story_views_; diff --git a/td/telegram/TdDb.cpp b/td/telegram/TdDb.cpp index 7f5d993fd..4dc9b76c9 100644 --- a/td/telegram/TdDb.cpp +++ b/td/telegram/TdDb.cpp @@ -128,6 +128,7 @@ Status init_binlog(Binlog &binlog, string path, BinlogKeyValue &binlog_p break; case LogEvent::HandlerType::DeleteStoryOnServer: case LogEvent::HandlerType::ReadStoriesOnServer: + case LogEvent::HandlerType::LoadDialogExpiringStories: events.to_story_manager.push_back(event.clone()); break; case LogEvent::HandlerType::UpdateScopeNotificationSettingsOnServer: diff --git a/td/telegram/logevent/LogEvent.h b/td/telegram/logevent/LogEvent.h index 4b7d5d247..80f853129 100644 --- a/td/telegram/logevent/LogEvent.h +++ b/td/telegram/logevent/LogEvent.h @@ -109,6 +109,7 @@ class LogEvent { SaveAppLog = 0x300, DeleteStoryOnServer = 0x400, ReadStoriesOnServer = 0x401, + LoadDialogExpiringStories = 0x402, ConfigPmcMagic = 0x1f18, BinlogPmcMagic = 0x4327 };