Load only specified number of chats from database.

GitOrigin-RevId: 5b2581b7313064dfea2f2c756c2cffb1af7ee00f
This commit is contained in:
levlam 2018-12-15 19:27:06 +03:00
parent 39c7df8000
commit aa1727f638
3 changed files with 65 additions and 32 deletions

View File

@ -8178,6 +8178,7 @@ void MessagesManager::recalc_unread_count() {
if (td_->auth_manager_->is_bot() || !need_unread_count_recalc_) { if (td_->auth_manager_->is_bot() || !need_unread_count_recalc_) {
return; return;
} }
LOG(INFO) << "Recalculate unread counts";
need_unread_count_recalc_ = false; need_unread_count_recalc_ = false;
is_message_unread_count_inited_ = true; is_message_unread_count_inited_ = true;
is_dialog_unread_count_inited_ = true; is_dialog_unread_count_inited_ = true;
@ -10905,21 +10906,27 @@ vector<DialogId> MessagesManager::get_dialogs(DialogDate offset, int32 limit, bo
return result; return result;
} }
load_dialog_list(std::move(promise)); load_dialog_list(limit, std::move(promise));
return result; return result;
} }
void MessagesManager::load_dialog_list(Promise<Unit> &&promise) { void MessagesManager::load_dialog_list(int32 limit, Promise<Unit> &&promise) {
LOG(INFO) << "Load dialog list with limit " << limit;
auto &multipromise = load_dialog_list_multipromise_; auto &multipromise = load_dialog_list_multipromise_;
multipromise.add_promise(std::move(promise)); multipromise.add_promise(std::move(promise));
bool use_database =
G()->parameters().use_message_db && last_loaded_database_dialog_date_ < last_database_server_dialog_date_;
if (multipromise.promise_count() != 1) { if (multipromise.promise_count() != 1) {
// queries have already been sent, just wait for the result // queries have already been sent, just wait for the result
if (use_database) {
load_dialog_list_limit_max_ = std::max(load_dialog_list_limit_max_, limit);
}
return; return;
} }
bool is_query_sent = false; bool is_query_sent = false;
if (G()->parameters().use_message_db && last_loaded_database_dialog_date_ < last_database_server_dialog_date_) { if (use_database) {
load_dialog_list_from_database(MAX_GET_DIALOGS, multipromise.get_promise()); load_dialog_list_from_database(limit, multipromise.get_promise());
is_query_sent = true; is_query_sent = true;
} else { } else {
LOG(INFO) << "Get dialogs from " << last_server_dialog_date_; LOG(INFO) << "Get dialogs from " << last_server_dialog_date_;
@ -10938,19 +10945,31 @@ void MessagesManager::load_dialog_list(Promise<Unit> &&promise) {
} }
void MessagesManager::load_dialog_list_from_database(int32 limit, Promise<Unit> &&promise) { void MessagesManager::load_dialog_list_from_database(int32 limit, Promise<Unit> &&promise) {
LOG(INFO) << "Load dialogs from " << last_loaded_database_dialog_date_ LOG(INFO) << "Load " << limit << " dialogs from database from " << last_loaded_database_dialog_date_
<< ", last database server dialog date = " << last_database_server_dialog_date_; << ", last database server dialog date = " << last_database_server_dialog_date_;
CHECK(load_dialog_list_limit_max_ == 0);
load_dialog_list_limit_max_ = limit;
G()->td_db()->get_dialog_db_async()->get_dialogs( G()->td_db()->get_dialog_db_async()->get_dialogs(
last_loaded_database_dialog_date_.get_order(), last_loaded_database_dialog_date_.get_dialog_id(), limit, last_loaded_database_dialog_date_.get_order(), last_loaded_database_dialog_date_.get_dialog_id(), limit,
PromiseCreator::lambda([actor_id = actor_id(this), PromiseCreator::lambda(
promise = std::move(promise)](vector<BufferSlice> result) mutable { [actor_id = actor_id(this), limit, promise = std::move(promise)](vector<BufferSlice> result) mutable {
send_closure(actor_id, &MessagesManager::on_get_dialogs_from_database, std::move(result), std::move(promise)); send_closure(actor_id, &MessagesManager::on_get_dialogs_from_database, limit, std::move(result),
})); std::move(promise));
}));
} }
void MessagesManager::on_get_dialogs_from_database(vector<BufferSlice> &&dialogs, Promise<Unit> &&promise) { void MessagesManager::on_get_dialogs_from_database(int32 limit, vector<BufferSlice> &&dialogs,
LOG(INFO) << "Receive " << dialogs.size() << " dialogs in result of GetDialogsFromDatabase"; Promise<Unit> &&promise) {
LOG(INFO) << "Receive " << dialogs.size() << " from expected " << limit
<< " dialogs in result of GetDialogsFromDatabase";
int32 new_get_dialogs_limit = 0;
int32 have_more_dialogs_in_database = (limit == static_cast<int32>(dialogs.size()));
if (have_more_dialogs_in_database && limit < load_dialog_list_limit_max_) {
new_get_dialogs_limit = load_dialog_list_limit_max_ - limit;
}
load_dialog_list_limit_max_ = 0;
DialogDate max_dialog_date = MIN_DIALOG_DATE; DialogDate max_dialog_date = MIN_DIALOG_DATE;
for (auto &dialog : dialogs) { for (auto &dialog : dialogs) {
Dialog *d = on_load_dialog_from_database(DialogId(), std::move(dialog)); Dialog *d = on_load_dialog_from_database(DialogId(), std::move(dialog));
@ -10965,36 +10984,44 @@ void MessagesManager::on_get_dialogs_from_database(vector<BufferSlice> &&dialogs
LOG(INFO) << "Chat " << dialog_date << " is loaded from database"; LOG(INFO) << "Chat " << dialog_date << " is loaded from database";
} }
if (dialogs.empty()) { if (!have_more_dialogs_in_database) {
// if there is no more dialogs in the database
last_loaded_database_dialog_date_ = MAX_DIALOG_DATE; last_loaded_database_dialog_date_ = MAX_DIALOG_DATE;
LOG(INFO) << "Set last loaded database dialog date to " << last_loaded_database_dialog_date_; LOG(INFO) << "Set last loaded database dialog date to " << last_loaded_database_dialog_date_;
last_server_dialog_date_ = max(last_server_dialog_date_, last_database_server_dialog_date_); last_server_dialog_date_ = max(last_server_dialog_date_, last_database_server_dialog_date_);
LOG(INFO) << "Set last server dialog date to " << last_server_dialog_date_; LOG(INFO) << "Set last server dialog date to " << last_server_dialog_date_;
update_last_dialog_date(); update_last_dialog_date();
} } else if (last_loaded_database_dialog_date_ < max_dialog_date) {
if (last_loaded_database_dialog_date_ < max_dialog_date) {
last_loaded_database_dialog_date_ = min(max_dialog_date, last_database_server_dialog_date_); last_loaded_database_dialog_date_ = min(max_dialog_date, last_database_server_dialog_date_);
LOG(INFO) << "Set last loaded database dialog date to " << last_loaded_database_dialog_date_; LOG(INFO) << "Set last loaded database dialog date to " << last_loaded_database_dialog_date_;
last_server_dialog_date_ = max(last_server_dialog_date_, last_loaded_database_dialog_date_); last_server_dialog_date_ = max(last_server_dialog_date_, last_loaded_database_dialog_date_);
LOG(INFO) << "Set last server dialog date to " << last_server_dialog_date_; LOG(INFO) << "Set last server dialog date to " << last_server_dialog_date_;
update_last_dialog_date(); update_last_dialog_date();
} else if (!dialogs.empty()) { } else {
LOG(ERROR) << "Last loaded database dialog date didn't increased"; LOG(ERROR) << "Last loaded database dialog date didn't increased";
} }
if (!preload_dialog_list_timeout_.has_timeout()) { if (!(last_loaded_database_dialog_date_ < last_database_server_dialog_date_)) {
LOG(INFO) << "Schedule chat list preload"; have_more_dialogs_in_database = false;
preload_dialog_list_timeout_.set_callback(std::move(MessagesManager::preload_dialog_list)); new_get_dialogs_limit = 0;
preload_dialog_list_timeout_.set_callback_data(static_cast<void *>(this));
} }
preload_dialog_list_timeout_.set_timeout_in(0.2);
promise.set_value(Unit()); if (new_get_dialogs_limit == 0) {
if (!preload_dialog_list_timeout_.has_timeout()) {
LOG(INFO) << "Schedule chat list preload";
preload_dialog_list_timeout_.set_callback(std::move(MessagesManager::preload_dialog_list));
preload_dialog_list_timeout_.set_callback_data(static_cast<void *>(this));
}
preload_dialog_list_timeout_.set_timeout_in(0.2);
promise.set_value(Unit());
} else {
load_dialog_list_from_database(new_get_dialogs_limit, std::move(promise));
}
} }
void MessagesManager::preload_dialog_list(void *messages_manager_void) { void MessagesManager::preload_dialog_list(void *messages_manager_void) {
if (G()->close_flag()) { if (G()->close_flag()) {
LOG(INFO) << "Skip chat list preload, because of closing";
return; return;
} }
@ -11003,7 +11030,7 @@ void MessagesManager::preload_dialog_list(void *messages_manager_void) {
CHECK(G()->parameters().use_message_db); CHECK(G()->parameters().use_message_db);
if (messages_manager->load_dialog_list_multipromise_.promise_count() != 0) { if (messages_manager->load_dialog_list_multipromise_.promise_count() != 0) {
// do nothing if there is pending load dialog list request LOG(INFO) << "Skip chat list preload, because there is a pending load chat list request";
return; return;
} }
@ -11015,13 +11042,14 @@ void MessagesManager::preload_dialog_list(void *messages_manager_void) {
if (messages_manager->last_loaded_database_dialog_date_ < messages_manager->last_database_server_dialog_date_) { if (messages_manager->last_loaded_database_dialog_date_ < messages_manager->last_database_server_dialog_date_) {
// if there are some dialogs in database, preload some of them // if there are some dialogs in database, preload some of them
messages_manager->load_dialog_list_from_database(20, Auto()); messages_manager->load_dialog_list(20, Auto());
} else if (messages_manager->last_dialog_date_ != MAX_DIALOG_DATE) { } else if (messages_manager->last_dialog_date_ != MAX_DIALOG_DATE) {
messages_manager->load_dialog_list(PromiseCreator::lambda([messages_manager](Result<Unit> result) { // otherwise load more dialogs from the server
if (result.is_ok()) { messages_manager->load_dialog_list(MAX_GET_DIALOGS, PromiseCreator::lambda([messages_manager](Result<Unit> result) {
messages_manager->recalc_unread_count(); if (result.is_ok()) {
} messages_manager->recalc_unread_count();
})); }
}));
} else { } else {
messages_manager->recalc_unread_count(); messages_manager->recalc_unread_count();
} }
@ -22366,7 +22394,7 @@ MessagesManager::Dialog *MessagesManager::get_dialog_force(DialogId dialog_id) {
CHECK(d == nullptr || d->dialog_id == dialog_id) << d->dialog_id << " " << dialog_id; CHECK(d == nullptr || d->dialog_id == dialog_id) << d->dialog_id << " " << dialog_id;
return d; return d;
} else { } else {
LOG(INFO) << "Failed to load " << dialog_id << " from database"; LOG(INFO) << "Failed to load " << dialog_id << " from database: " << r_value.error().message();
return nullptr; return nullptr;
} }
} }

View File

@ -1426,7 +1426,7 @@ class MessagesManager : public Actor {
void on_save_dialog_to_database(DialogId dialog_id, bool success); void on_save_dialog_to_database(DialogId dialog_id, bool success);
void load_dialog_list(Promise<Unit> &&promise); void load_dialog_list(int32 limit, Promise<Unit> &&promise);
void load_dialog_list_from_database(int32 limit, Promise<Unit> &&promise); void load_dialog_list_from_database(int32 limit, Promise<Unit> &&promise);
@ -1663,7 +1663,7 @@ class MessagesManager : public Actor {
Dialog *on_load_dialog_from_database(DialogId dialog_id, const BufferSlice &value); Dialog *on_load_dialog_from_database(DialogId dialog_id, const BufferSlice &value);
void on_get_dialogs_from_database(vector<BufferSlice> &&dialogs, Promise<Unit> &&promise); void on_get_dialogs_from_database(int32 limit, vector<BufferSlice> &&dialogs, Promise<Unit> &&promise);
void send_get_dialog_query(DialogId dialog_id, Promise<Unit> &&promise, uint64 logevent_id = 0); void send_get_dialog_query(DialogId dialog_id, Promise<Unit> &&promise, uint64 logevent_id = 0);
@ -2166,6 +2166,7 @@ class MessagesManager : public Actor {
MultiPromiseActor load_dialog_list_multipromise_{ MultiPromiseActor load_dialog_list_multipromise_{
"LoadDialogListMultiPromiseActor"}; // should be defined before pending_on_get_dialogs_ "LoadDialogListMultiPromiseActor"}; // should be defined before pending_on_get_dialogs_
int32 load_dialog_list_limit_max_ = 0;
Timeout preload_dialog_list_timeout_; Timeout preload_dialog_list_timeout_;
std::unordered_map<DialogId, string, DialogIdHash> active_get_channel_differencies_; std::unordered_map<DialogId, string, DialogIdHash> active_get_channel_differencies_;

View File

@ -1518,6 +1518,10 @@ class CliClient final : public Actor {
} }
send_request( send_request(
make_tl_object<td_api::getChats>(offset_order, as_chat_id(offset_chat_id), to_integer<int32>(limit))); make_tl_object<td_api::getChats>(offset_order, as_chat_id(offset_chat_id), to_integer<int32>(limit)));
} else if (op == "gctest") {
send_request(make_tl_object<td_api::getChats>(std::numeric_limits<int64>::max(), 0, 1));
send_request(make_tl_object<td_api::getChats>(std::numeric_limits<int64>::max(), 0, 10));
send_request(make_tl_object<td_api::getChats>(std::numeric_limits<int64>::max(), 0, 5));
} else if (op == "gcc" || op == "GetCommonChats") { } else if (op == "gcc" || op == "GetCommonChats") {
string user_id; string user_id;
string offset_chat_id; string offset_chat_id;