Unite requests for getting full language pack.

GitOrigin-RevId: 401ccd4168f56c555af1a7827384395dcf906fc0
This commit is contained in:
levlam 2018-08-24 04:53:14 +03:00
parent 4238f28a19
commit bcadd6a459
4 changed files with 101 additions and 9 deletions

View File

@ -367,7 +367,7 @@ bool LanguagePackManager::language_has_strings(Language *language, const vector<
return true;
}
if (keys.empty()) {
return language->version_ != -1 && language->is_full_;
return false; // language is already checked to be not full
}
for (auto &key : keys) {
if (!language_has_string_unsafe(language, key)) {
@ -596,9 +596,22 @@ void LanguagePackManager::get_language_pack_strings(string language_code, vector
}
if (keys.empty()) {
auto &queries = get_all_language_pack_strings_queries_[language_pack_][language_code].queries_;
queries.push_back(std::move(promise));
if (queries.size() != 1) {
// send request only once
return;
}
auto result_promise =
PromiseCreator::lambda([actor_id = actor_id(this), language_pack = language_pack_, language_code](
Result<td_api::object_ptr<td_api::languagePackStrings>> r_strings) mutable {
send_closure(actor_id, &LanguagePackManager::on_get_all_language_pack_strings, language_pack, language_code,
std::move(r_strings));
});
auto request_promise =
PromiseCreator::lambda([actor_id = actor_id(this), language_pack = language_pack_, language_code,
promise = std::move(promise)](Result<NetQueryPtr> r_query) mutable {
promise = std::move(result_promise)](Result<NetQueryPtr> r_query) mutable {
auto r_result = fetch_result<telegram_api::langpack_getLangPack>(std::move(r_query));
if (r_result.is_error()) {
return promise.set_error(r_result.move_as_error());
@ -636,6 +649,76 @@ void LanguagePackManager::get_language_pack_strings(string language_code, vector
}
}
static td_api::object_ptr<td_api::LanguagePackStringValue> copy_language_pack_string_value(
const td_api::LanguagePackStringValue *value) {
switch (value->get_id()) {
case td_api::languagePackStringValueOrdinary::ID: {
auto old_value = static_cast<const td_api::languagePackStringValueOrdinary *>(value);
return make_tl_object<td_api::languagePackStringValueOrdinary>(old_value->value_);
}
case td_api::languagePackStringValuePluralized::ID: {
auto old_value = static_cast<const td_api::languagePackStringValuePluralized *>(value);
return make_tl_object<td_api::languagePackStringValuePluralized>(
std::move(old_value->zero_value_), std::move(old_value->one_value_), std::move(old_value->two_value_),
std::move(old_value->few_value_), std::move(old_value->many_value_), std::move(old_value->other_value_));
}
case td_api::languagePackStringValueDeleted::ID:
return make_tl_object<td_api::languagePackStringValueDeleted>();
default:
UNREACHABLE();
return nullptr;
}
}
void LanguagePackManager::on_get_all_language_pack_strings(
string language_pack, string language_code, Result<td_api::object_ptr<td_api::languagePackStrings>> r_strings) {
auto &queries = get_all_language_pack_strings_queries_[language_pack][language_code].queries_;
auto promises = std::move(queries);
CHECK(!promises.empty());
auto it = get_all_language_pack_strings_queries_.find(language_pack);
it->second.erase(language_code);
if (it->second.empty()) {
get_all_language_pack_strings_queries_.erase(it);
}
if (r_strings.is_error()) {
for (auto &promise : promises) {
promise.set_error(r_strings.error().clone());
}
return;
}
auto strings = r_strings.move_as_ok();
size_t left_non_empty_promise_count = 0;
for (auto &promise : promises) {
if (promise) {
left_non_empty_promise_count++;
}
}
for (auto &promise : promises) {
if (promise) {
if (left_non_empty_promise_count == 1) {
LOG(INFO) << "Set last non-empty promise";
promise.set_value(std::move(strings));
} else {
LOG(INFO) << "Set non-empty promise";
vector<td_api::object_ptr<td_api::languagePackString>> strings_copy;
for (auto &result : strings->strings_) {
CHECK(result != nullptr);
strings_copy.push_back(td_api::make_object<td_api::languagePackString>(
result->key_, copy_language_pack_string_value(result->value_.get())));
}
promise.set_value(td_api::make_object<td_api::languagePackStrings>(std::move(strings_copy)));
}
left_non_empty_promise_count--;
} else {
LOG(INFO) << "Set empty promise";
promise.set_value(nullptr);
}
}
CHECK(left_non_empty_promise_count == 0);
}
td_api::object_ptr<td_api::Object> LanguagePackManager::get_language_pack_string(const string &database_path,
const string &language_pack,
const string &language_code,

View File

@ -80,6 +80,12 @@ class LanguagePackManager : public NetQueryCallback {
string language_code_;
LanguageDatabase *database_ = nullptr;
struct PendingQueries {
vector<Promise<td_api::object_ptr<td_api::languagePackStrings>>> queries_;
};
std::unordered_map<string, std::unordered_map<string, PendingQueries>> get_all_language_pack_strings_queries_;
static int32 manager_count_;
static std::mutex language_database_mutex_;
@ -132,6 +138,9 @@ class LanguagePackManager : public NetQueryCallback {
vector<string> keys, vector<tl_object_ptr<telegram_api::LangPackString>> results,
Promise<td_api::object_ptr<td_api::languagePackStrings>> promise);
void on_get_all_language_pack_strings(string language_pack, string language_code,
Result<td_api::object_ptr<td_api::languagePackStrings>> r_strings);
void on_failed_get_difference(string language_pack, string language_code);
void on_get_languages(vector<tl_object_ptr<telegram_api::langPackLanguage>> languages, string language_pack,

View File

@ -7557,7 +7557,7 @@ void MessagesManager::on_get_public_dialogs_search_result(const string &query,
vector<tl_object_ptr<telegram_api::Peer>> &&peers) {
auto it = search_public_dialogs_queries_.find(query);
CHECK(it != search_public_dialogs_queries_.end());
CHECK(it->second.size() > 0);
CHECK(!it->second.empty());
auto promises = std::move(it->second);
search_public_dialogs_queries_.erase(it);
@ -7572,7 +7572,7 @@ void MessagesManager::on_get_public_dialogs_search_result(const string &query,
void MessagesManager::on_failed_public_dialogs_search(const string &query, Status &&error) {
auto it = search_public_dialogs_queries_.find(query);
CHECK(it != search_public_dialogs_queries_.end());
CHECK(it->second.size() > 0);
CHECK(!it->second.empty());
auto promises = std::move(it->second);
search_public_dialogs_queries_.erase(it);
@ -12291,7 +12291,7 @@ vector<DialogId> MessagesManager::get_common_dialogs(UserId user_id, DialogId of
void MessagesManager::on_get_common_dialogs(UserId user_id, vector<tl_object_ptr<telegram_api::Chat>> &&chats,
int32 total_count) {
auto &result = found_common_dialogs_[user_id];
if (result.size() > 0 && result.back() == DialogId()) {
if (!result.empty() && result.back() == DialogId()) {
return;
}
for (auto &chat : chats) {
@ -20821,7 +20821,7 @@ void MessagesManager::send_get_dialog_notification_settings_query(DialogId dialo
void MessagesManager::on_get_dialog_notification_settings_query_finished(DialogId dialog_id, Status &&status) {
auto it = get_dialog_notification_settings_queries_.find(dialog_id);
CHECK(it != get_dialog_notification_settings_queries_.end());
CHECK(it->second.size() > 0);
CHECK(!it->second.empty());
auto promises = std::move(it->second);
get_dialog_notification_settings_queries_.erase(it);
@ -20893,7 +20893,7 @@ void MessagesManager::send_get_dialog_query(DialogId dialog_id, Promise<Unit> &&
void MessagesManager::on_get_dialog_query_finished(DialogId dialog_id, Status &&status) {
auto it = get_dialog_queries_.find(dialog_id);
CHECK(it != get_dialog_queries_.end());
CHECK(it->second.size() > 0);
CHECK(!it->second.empty());
auto promises = std::move(it->second);
get_dialog_queries_.erase(it);
@ -24476,7 +24476,7 @@ bool MessagesManager::update_message_content(DialogId dialog_id, Message *old_me
}
if (old_photo->photos != new_photo->photos) {
if ((old_photo->photos.size() == 1 || (old_photo->photos.size() == 2 && old_photo->photos[0].type == 't')) &&
old_photo->photos.back().type == 'i' && new_photo->photos.size() > 0) {
old_photo->photos.back().type == 'i' && !new_photo->photos.empty()) {
// first time get info about sent photo
if (old_photo->photos.size() == 2) {
new_photo->photos.push_back(old_photo->photos[0]);

View File

@ -2706,7 +2706,7 @@ std::pair<int32, vector<int64>> StickersManager::get_archived_sticker_sets(bool
void StickersManager::on_get_archived_sticker_sets(
bool is_masks, vector<tl_object_ptr<telegram_api::StickerSetCovered>> &&sticker_sets, int32 total_count) {
vector<int64> &sticker_set_ids = archived_sticker_set_ids_[is_masks];
if (sticker_set_ids.size() > 0 && sticker_set_ids.back() == 0) {
if (!sticker_set_ids.empty() && sticker_set_ids.back() == 0) {
return;
}