From 970f65604a468acbfce03d092afa0c1cfcae6697 Mon Sep 17 00:00:00 2001 From: levlam Date: Tue, 5 Jan 2021 16:06:51 +0300 Subject: [PATCH] Switch back from getDifference to updates handling if there are too much of them. --- td/telegram/UpdatesManager.cpp | 75 ++++++++++++++++++++++++++++++---- td/telegram/UpdatesManager.h | 6 +++ 2 files changed, 74 insertions(+), 7 deletions(-) diff --git a/td/telegram/UpdatesManager.cpp b/td/telegram/UpdatesManager.cpp index 26b7f9428..8bba83e9f 100644 --- a/td/telegram/UpdatesManager.cpp +++ b/td/telegram/UpdatesManager.cpp @@ -224,12 +224,26 @@ void UpdatesManager::get_difference(const char *source) { VLOG(get_difference) << "Skip running getDifference from " << source << " because it is already running"; return; } + + run_get_difference(false, source); +} + +void UpdatesManager::run_get_difference(bool is_recursive, const char *source) { + CHECK(get_pts() != -1); + CHECK(td_->auth_manager_->is_authorized()); + CHECK(!running_get_difference_); + running_get_difference_ = true; VLOG(get_difference) << "-----BEGIN GET DIFFERENCE----- from " << source; before_get_difference(false); + if (!is_recursive) { + min_postponed_update_pts_ = 0; + min_postponed_update_qts_ = 0; + } + td_->create_handler()->send(); last_get_difference_pts_ = get_pts(); } @@ -1137,6 +1151,11 @@ void UpdatesManager::on_get_difference(tl_object_ptrauth_manager_->is_authorized()) { + // just in case + return; + } + if (difference_ptr == nullptr) { on_failed_get_difference(); return; @@ -1192,8 +1211,10 @@ void UpdatesManager::on_get_difference(tl_object_ptr(difference_ptr); + bool is_pts_changed = have_update_pts_changed(difference->other_updates_); if (difference->intermediate_state_->pts_ >= get_pts() && get_pts() != std::numeric_limits::max() && - difference->intermediate_state_->date_ >= date_ && difference->intermediate_state_->qts_ == get_qts()) { + difference->intermediate_state_->date_ >= date_ && difference->intermediate_state_->qts_ == get_qts() && + !is_pts_changed) { // TODO send new getDifference request and apply difference slice only after that } @@ -1206,12 +1227,28 @@ void UpdatesManager::on_get_difference(tl_object_ptrnew_encrypted_messages_), std::move(difference->other_updates_)); if (running_get_difference_) { - LOG(ERROR) << "Get difference has run while processing get difference updates"; + if (!is_pts_changed) { + LOG(ERROR) << "Get difference has run while processing get difference updates"; + } + break; + } + CHECK(!is_pts_changed); + + auto state = std::move(difference->intermediate_state_); + if (get_pts() != std::numeric_limits::max() && state->date_ == get_date() && + (state->pts_ == get_pts() || + (min_postponed_update_pts_ != 0 && state->pts_ >= min_postponed_update_pts_ + 1000)) && + (state->qts_ == get_qts() || + (min_postponed_update_qts_ != 0 && state->qts_ >= min_postponed_update_qts_ + 1000))) { + on_get_updates_state(std::move(state), "get difference final slice"); + VLOG(get_difference) << "Trying to switch back from getDifference to update processing"; break; } - on_get_updates_state(std::move(difference->intermediate_state_), "get difference slice"); - get_difference("on updates_differenceSlice"); + on_get_updates_state(std::move(state), "get difference slice"); + if (get_pts() != -1) { // just in case + run_get_difference(true, "on updates_differenceSlice"); + } break; } case telegram_api::updates_differenceTooLong::ID: { @@ -1246,7 +1283,8 @@ void UpdatesManager::after_get_difference() { } if (postponed_updates_.size()) { - VLOG(get_difference) << "Begin to apply " << postponed_updates_.size() << " postponed updates"; + VLOG(get_difference) << "Begin to apply " << postponed_updates_.size() << " postponed update chunks"; + size_t total_update_count = 0; while (!postponed_updates_.empty()) { auto it = postponed_updates_.begin(); auto updates = std::move(it->second.updates); @@ -1255,15 +1293,18 @@ void UpdatesManager::after_get_difference() { auto promise = std::move(it->second.promise); // ignore it->second.date, because it may be too old postponed_updates_.erase(it); + auto update_count = updates.size(); on_pending_updates(std::move(updates), updates_seq_begin, updates_seq_end, 0, std::move(promise), "postponed updates"); if (running_get_difference_) { VLOG(get_difference) << "Finish to apply postponed updates with " << postponed_updates_.size() - << " updates left, because forced to run getDifference"; + << " updates left after applied " << total_update_count + << " updates, because forced to run getDifference"; return; } + total_update_count += update_count; } - VLOG(get_difference) << "Finish to apply postponed updates"; + VLOG(get_difference) << "Finish to apply " << total_update_count << " postponed updates"; } td_->animations_manager_->after_get_difference(); @@ -1300,6 +1341,16 @@ void UpdatesManager::on_pending_updates(vector> &updates) { + for (auto &update : updates) { + CHECK(update != nullptr); + if (update->get_id() == telegram_api::updatePtsChanged::ID) { + return true; + } + } + return false; +} + int32 UpdatesManager::get_update_pts(const telegram_api::Update *update) { switch (update->get_id()) { case telegram_api::updateNewMessage::ID: diff --git a/td/telegram/UpdatesManager.h b/td/telegram/UpdatesManager.h index 1f42d3a30..147e3f1bd 100644 --- a/td/telegram/UpdatesManager.h +++ b/td/telegram/UpdatesManager.h @@ -133,6 +133,8 @@ class UpdatesManager : public Actor { bool running_get_difference_ = false; int32 last_get_difference_pts_ = 0; + int32 min_postponed_update_pts_ = 0; + int32 min_postponed_update_qts_ = 0; void tear_down() override; @@ -184,12 +186,16 @@ class UpdatesManager : public Actor { void set_qts_gap_timeout(double timeout); + void run_get_difference(bool is_recursive, const char *source); + void on_failed_get_difference(); void before_get_difference(bool is_initial); void after_get_difference(); + static bool have_update_pts_changed(const vector> &updates); + static int32 get_update_pts(const telegram_api::Update *update); static int32 get_update_qts(const telegram_api::Update *update);