Extract pts and qts updates and apply them during getDifference.
This commit is contained in:
parent
a7e2e85119
commit
241718eae8
|
@ -1338,15 +1338,8 @@ void UpdatesManager::on_get_difference(tl_object_ptr<telegram_api::updates_Diffe
|
||||||
auto difference = move_tl_object_as<telegram_api::updates_differenceEmpty>(difference_ptr);
|
auto difference = move_tl_object_as<telegram_api::updates_differenceEmpty>(difference_ptr);
|
||||||
set_date(difference->date_, false, "on_get_difference_empty");
|
set_date(difference->date_, false, "on_get_difference_empty");
|
||||||
seq_ = difference->seq_;
|
seq_ = difference->seq_;
|
||||||
if (!pending_seq_updates_.empty()) {
|
|
||||||
LOG(WARNING) << "Drop " << pending_seq_updates_.size() << " pending seq updates after receive empty difference";
|
|
||||||
auto pending_seq_updates = std::move(pending_seq_updates_);
|
|
||||||
pending_seq_updates_.clear();
|
|
||||||
|
|
||||||
for (auto &pending_update : pending_seq_updates) {
|
process_pending_qts_updates();
|
||||||
pending_update.second.promise.set_value(Unit());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!pending_qts_updates_.empty()) {
|
if (!pending_qts_updates_.empty()) {
|
||||||
LOG(WARNING) << "Drop " << pending_qts_updates_.size() << " pending qts updates after receive empty difference";
|
LOG(WARNING) << "Drop " << pending_qts_updates_.size() << " pending qts updates after receive empty difference";
|
||||||
auto pending_qts_updates = std::move(pending_qts_updates_);
|
auto pending_qts_updates = std::move(pending_qts_updates_);
|
||||||
|
@ -1359,6 +1352,17 @@ void UpdatesManager::on_get_difference(tl_object_ptr<telegram_api::updates_Diffe
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
process_pending_seq_updates();
|
||||||
|
if (!pending_seq_updates_.empty()) {
|
||||||
|
LOG(WARNING) << "Drop " << pending_seq_updates_.size() << " pending seq updates after receive empty difference";
|
||||||
|
auto pending_seq_updates = std::move(pending_seq_updates_);
|
||||||
|
pending_seq_updates_.clear();
|
||||||
|
|
||||||
|
for (auto &pending_update : pending_seq_updates) {
|
||||||
|
pending_update.second.promise.set_value(Unit());
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case telegram_api::updates_difference::ID: {
|
case telegram_api::updates_difference::ID: {
|
||||||
|
@ -1564,78 +1568,62 @@ void UpdatesManager::on_pending_updates(vector<tl_object_ptr<telegram_api::Updat
|
||||||
}
|
}
|
||||||
|
|
||||||
bool need_postpone = running_get_difference_ /*|| string(source) != string("postponed updates")*/;
|
bool need_postpone = running_get_difference_ /*|| string(source) != string("postponed updates")*/;
|
||||||
if (need_postpone) {
|
if (!need_postpone) {
|
||||||
LOG(INFO) << "Postpone " << updates.size() << " updates [" << seq_begin << ", " << seq_end
|
|
||||||
<< "] with date = " << date << " from " << source;
|
|
||||||
for (auto &update : updates) {
|
for (auto &update : updates) {
|
||||||
auto pts = get_update_pts(update.get());
|
if (!is_acceptable_update(update.get())) {
|
||||||
if (pts != 0 && (min_postponed_update_pts_ == 0 || pts < min_postponed_update_pts_)) {
|
CHECK(update != nullptr);
|
||||||
min_postponed_update_pts_ = pts;
|
int32 id = update->get_id();
|
||||||
}
|
const tl_object_ptr<telegram_api::Message> *message_ptr = nullptr;
|
||||||
auto qts = get_update_qts(update.get());
|
int32 pts = 0;
|
||||||
if (qts != 0 && (min_postponed_update_qts_ == 0 || qts < min_postponed_update_qts_)) {
|
if (id == telegram_api::updateNewChannelMessage::ID) {
|
||||||
min_postponed_update_qts_ = qts;
|
auto update_new_channel_message = static_cast<const telegram_api::updateNewChannelMessage *>(update.get());
|
||||||
}
|
message_ptr = &update_new_channel_message->message_;
|
||||||
}
|
pts = update_new_channel_message->pts_;
|
||||||
postponed_updates_.emplace(
|
|
||||||
seq_begin, PendingSeqUpdates(seq_begin, seq_end, date, receive_time, std::move(updates), std::move(promise)));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto &update : updates) {
|
|
||||||
if (!is_acceptable_update(update.get())) {
|
|
||||||
CHECK(update != nullptr);
|
|
||||||
int32 id = update->get_id();
|
|
||||||
const tl_object_ptr<telegram_api::Message> *message_ptr = nullptr;
|
|
||||||
int32 pts = 0;
|
|
||||||
if (id == telegram_api::updateNewChannelMessage::ID) {
|
|
||||||
auto update_new_channel_message = static_cast<const telegram_api::updateNewChannelMessage *>(update.get());
|
|
||||||
message_ptr = &update_new_channel_message->message_;
|
|
||||||
pts = update_new_channel_message->pts_;
|
|
||||||
}
|
|
||||||
if (id == telegram_api::updateEditChannelMessage::ID) {
|
|
||||||
auto update_edit_channel_message = static_cast<const telegram_api::updateEditChannelMessage *>(update.get());
|
|
||||||
message_ptr = &update_edit_channel_message->message_;
|
|
||||||
pts = update_edit_channel_message->pts_;
|
|
||||||
}
|
|
||||||
|
|
||||||
// for channels we can try to replace unacceptable update with updateChannelTooLong
|
|
||||||
if (message_ptr != nullptr) {
|
|
||||||
auto dialog_id = td_->messages_manager_->get_message_dialog_id(*message_ptr);
|
|
||||||
if (dialog_id.get_type() == DialogType::Channel) {
|
|
||||||
auto channel_id = dialog_id.get_channel_id();
|
|
||||||
if (td_->contacts_manager_->have_channel_force(channel_id)) {
|
|
||||||
if (td_->messages_manager_->is_old_channel_update(dialog_id, pts)) {
|
|
||||||
// the update will be ignored anyway, so there is no reason to replace it or force get_difference
|
|
||||||
LOG(INFO) << "Allow an outdated unacceptable update from " << source;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if ((*message_ptr)->get_id() != telegram_api::messageService::ID) {
|
|
||||||
// don't replace service messages, because they can be about bot's kicking
|
|
||||||
LOG(INFO) << "Replace update about new message with updateChannelTooLong in " << dialog_id;
|
|
||||||
update = telegram_api::make_object<telegram_api::updateChannelTooLong>(
|
|
||||||
telegram_api::updateChannelTooLong::PTS_MASK, channel_id.get(), pts);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
LOG(ERROR) << "Update is not from a channel: " << to_string(update);
|
|
||||||
}
|
}
|
||||||
|
if (id == telegram_api::updateEditChannelMessage::ID) {
|
||||||
|
auto update_edit_channel_message = static_cast<const telegram_api::updateEditChannelMessage *>(update.get());
|
||||||
|
message_ptr = &update_edit_channel_message->message_;
|
||||||
|
pts = update_edit_channel_message->pts_;
|
||||||
|
}
|
||||||
|
|
||||||
|
// for channels we can try to replace unacceptable update with updateChannelTooLong
|
||||||
|
if (message_ptr != nullptr) {
|
||||||
|
auto dialog_id = td_->messages_manager_->get_message_dialog_id(*message_ptr);
|
||||||
|
if (dialog_id.get_type() == DialogType::Channel) {
|
||||||
|
auto channel_id = dialog_id.get_channel_id();
|
||||||
|
if (td_->contacts_manager_->have_channel_force(channel_id)) {
|
||||||
|
if (td_->messages_manager_->is_old_channel_update(dialog_id, pts)) {
|
||||||
|
// the update will be ignored anyway, so there is no reason to replace it or force get_difference
|
||||||
|
LOG(INFO) << "Allow an outdated unacceptable update from " << source;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ((*message_ptr)->get_id() != telegram_api::messageService::ID) {
|
||||||
|
// don't replace service messages, because they can be about bot's kicking
|
||||||
|
LOG(INFO) << "Replace update about new message with updateChannelTooLong in " << dialog_id;
|
||||||
|
update = telegram_api::make_object<telegram_api::updateChannelTooLong>(
|
||||||
|
telegram_api::updateChannelTooLong::PTS_MASK, channel_id.get(), pts);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
LOG(ERROR) << "Update is not from a channel: " << to_string(update);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
get_difference("on unacceptable updates in on_pending_updates");
|
||||||
|
return promise.set_value(Unit());
|
||||||
}
|
}
|
||||||
|
|
||||||
get_difference("on unacceptable updates in on_pending_updates");
|
|
||||||
return promise.set_value(Unit());
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (date > 0 && updates.size() == 1 && updates[0] != nullptr &&
|
if (date > 0 && updates.size() == 1 && updates[0] != nullptr &&
|
||||||
updates[0]->get_id() == telegram_api::updateReadHistoryOutbox::ID) {
|
updates[0]->get_id() == telegram_api::updateReadHistoryOutbox::ID) {
|
||||||
auto update = static_cast<const telegram_api::updateReadHistoryOutbox *>(updates[0].get());
|
auto update = static_cast<const telegram_api::updateReadHistoryOutbox *>(updates[0].get());
|
||||||
DialogId dialog_id(update->peer_);
|
DialogId dialog_id(update->peer_);
|
||||||
if (dialog_id.get_type() == DialogType::User) {
|
if (dialog_id.get_type() == DialogType::User) {
|
||||||
auto user_id = dialog_id.get_user_id();
|
auto user_id = dialog_id.get_user_id();
|
||||||
if (user_id.is_valid()) {
|
if (user_id.is_valid()) {
|
||||||
td_->contacts_manager_->on_update_user_local_was_online(user_id, date);
|
td_->contacts_manager_->on_update_user_local_was_online(user_id, date);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1659,7 +1647,9 @@ void UpdatesManager::on_pending_updates(vector<tl_object_ptr<telegram_api::Updat
|
||||||
for (auto &update : updates) {
|
for (auto &update : updates) {
|
||||||
LOG(ERROR) << "Update: " << oneline(to_string(update));
|
LOG(ERROR) << "Update: " << oneline(to_string(update));
|
||||||
}
|
}
|
||||||
schedule_get_difference("on_get_wrong_updates");
|
if (!running_get_difference_) {
|
||||||
|
schedule_get_difference("on_get_wrong_updates");
|
||||||
|
}
|
||||||
return promise.set_value(Unit());
|
return promise.set_value(Unit());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1697,27 +1687,34 @@ void UpdatesManager::on_pending_updates(vector<tl_object_ptr<telegram_api::Updat
|
||||||
on_update(move_tl_object_as<telegram_api::updateEncryption>(update), mpas.get_promise());
|
on_update(move_tl_object_as<telegram_api::updateEncryption>(update), mpas.get_promise());
|
||||||
update = nullptr;
|
update = nullptr;
|
||||||
}
|
}
|
||||||
CHECK(!running_get_difference_);
|
CHECK(need_postpone || !running_get_difference_);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto &update : updates) {
|
for (auto &update : updates) {
|
||||||
if (update != nullptr) {
|
if (update != nullptr) {
|
||||||
if (is_pts_update(update.get()) || is_qts_update(update.get())) {
|
if (is_pts_update(update.get())) {
|
||||||
|
if (running_get_difference_) {
|
||||||
|
auto pts = get_update_pts(update.get());
|
||||||
|
if (pts != 0 && (min_postponed_update_pts_ == 0 || pts < min_postponed_update_pts_)) {
|
||||||
|
min_postponed_update_pts_ = pts;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
downcast_call(*update, OnUpdate(this, update, mpas.get_promise()));
|
||||||
|
update = nullptr;
|
||||||
|
} else if (is_qts_update(update.get())) {
|
||||||
|
if (running_get_difference_) {
|
||||||
|
auto qts = get_update_qts(update.get());
|
||||||
|
if (qts != 0 && (min_postponed_update_qts_ == 0 || qts < min_postponed_update_qts_)) {
|
||||||
|
min_postponed_update_qts_ = qts;
|
||||||
|
}
|
||||||
|
}
|
||||||
downcast_call(*update, OnUpdate(this, update, mpas.get_promise()));
|
downcast_call(*update, OnUpdate(this, update, mpas.get_promise()));
|
||||||
update = nullptr;
|
update = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (running_get_difference_) {
|
|
||||||
LOG(ERROR) << "Postpone " << updates.size() << " updates [" << seq_begin << ", " << seq_end
|
|
||||||
<< "] with date = " << date << " from " << source;
|
|
||||||
postponed_updates_.emplace(
|
|
||||||
seq_begin, PendingSeqUpdates(seq_begin, seq_end, date, receive_time, std::move(updates), mpas.get_promise()));
|
|
||||||
return lock.set_value(Unit());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (seq_begin == 0 && seq_end == 0) {
|
if (seq_begin == 0 && seq_end == 0) {
|
||||||
bool have_updates = false;
|
bool have_updates = false;
|
||||||
for (auto &update : updates) {
|
for (auto &update : updates) {
|
||||||
|
@ -1727,11 +1724,22 @@ void UpdatesManager::on_pending_updates(vector<tl_object_ptr<telegram_api::Updat
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!have_updates) {
|
if (!have_updates) {
|
||||||
LOG(INFO) << "All updates was processed";
|
LOG(INFO) << "All updates were processed";
|
||||||
return lock.set_value(Unit());
|
return lock.set_value(Unit());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (need_postpone || running_get_difference_) {
|
||||||
|
LOG(INFO) << "Postpone " << updates.size() << " updates [" << seq_begin << ", " << seq_end
|
||||||
|
<< "] with date = " << date << " from " << source;
|
||||||
|
if (!need_postpone) {
|
||||||
|
LOG(ERROR) << "Run get difference while applying updates from " << source;
|
||||||
|
}
|
||||||
|
postponed_updates_.emplace(
|
||||||
|
seq_begin, PendingSeqUpdates(seq_begin, seq_end, date, receive_time, std::move(updates), mpas.get_promise()));
|
||||||
|
return lock.set_value(Unit());
|
||||||
|
}
|
||||||
|
|
||||||
if (seq_begin == 0 || seq_begin == seq_ + 1) {
|
if (seq_begin == 0 || seq_begin == seq_ + 1) {
|
||||||
LOG(INFO) << "Process " << updates.size() << " updates [" << seq_begin << ", " << seq_end
|
LOG(INFO) << "Process " << updates.size() << " updates [" << seq_begin << ", " << seq_end
|
||||||
<< "] with date = " << date << " from " << source;
|
<< "] with date = " << date << " from " << source;
|
||||||
|
@ -1792,11 +1800,9 @@ void UpdatesManager::add_pending_qts_update(tl_object_ptr<telegram_api::Update>
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
CHECK(!running_get_difference_);
|
if (running_get_difference_ || (qts - 1 > old_qts && old_qts > 0)) {
|
||||||
|
|
||||||
if (qts - 1 > old_qts && old_qts > 0) {
|
|
||||||
LOG(INFO) << "Postpone update with qts = " << qts;
|
LOG(INFO) << "Postpone update with qts = " << qts;
|
||||||
if (pending_qts_updates_.empty()) {
|
if (!running_get_difference_ && pending_qts_updates_.empty()) {
|
||||||
set_qts_gap_timeout(MAX_UNFILLED_GAP_TIME);
|
set_qts_gap_timeout(MAX_UNFILLED_GAP_TIME);
|
||||||
}
|
}
|
||||||
auto &pending_update = pending_qts_updates_[qts];
|
auto &pending_update = pending_qts_updates_[qts];
|
||||||
|
@ -1976,9 +1982,6 @@ void UpdatesManager::add_pending_pts_update(tl_object_ptr<telegram_api::Update>
|
||||||
|
|
||||||
if (running_get_difference_ || !postponed_pts_updates_.empty()) {
|
if (running_get_difference_ || !postponed_pts_updates_.empty()) {
|
||||||
LOG(INFO) << "Save pending update got while running getDifference from " << source;
|
LOG(INFO) << "Save pending update got while running getDifference from " << source;
|
||||||
if (running_get_difference_) {
|
|
||||||
CHECK(update->get_id() == dummyUpdate::ID || update->get_id() == updateSentMessage::ID);
|
|
||||||
}
|
|
||||||
postpone_pts_update(std::move(update), new_pts, pts_count, receive_time, std::move(promise));
|
postpone_pts_update(std::move(update), new_pts, pts_count, receive_time, std::move(promise));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -2360,6 +2363,7 @@ void UpdatesManager::process_pending_qts_updates() {
|
||||||
}
|
}
|
||||||
set_qts_gap_timeout(receive_time + MAX_UNFILLED_GAP_TIME - Time::now());
|
set_qts_gap_timeout(receive_time + MAX_UNFILLED_GAP_TIME - Time::now());
|
||||||
}
|
}
|
||||||
|
CHECK(!running_get_difference_);
|
||||||
}
|
}
|
||||||
|
|
||||||
void UpdatesManager::set_pts_gap_timeout(double timeout) {
|
void UpdatesManager::set_pts_gap_timeout(double timeout) {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user