Combine simultaneous SearchPublicChats queries.

GitOrigin-RevId: f51ed555b0758ef0cdf8afb73f276dbeb687e70e
This commit is contained in:
levlam 2018-01-16 19:04:36 +03:00
parent ee37765a24
commit 5445d920b1
2 changed files with 49 additions and 22 deletions

View File

@ -465,17 +465,13 @@ class GetDialogListQuery : public NetActorOnce {
}; };
class SearchPublicDialogsQuery : public Td::ResultHandler { class SearchPublicDialogsQuery : public Td::ResultHandler {
Promise<Unit> promise_;
string query_; string query_;
public: public:
explicit SearchPublicDialogsQuery(Promise<Unit> &&promise) : promise_(std::move(promise)) {
}
void send(const string &query) { void send(const string &query) {
query_ = query; query_ = query;
send_query(G()->net_query_creator().create( send_query(G()->net_query_creator().create(
create_storer(telegram_api::contacts_search(query, 100 /* ignored server-side */)))); create_storer(telegram_api::contacts_search(query, 3 /* ignored server-side */))));
} }
void on_result(uint64 id, BufferSlice packet) override { void on_result(uint64 id, BufferSlice packet) override {
@ -489,14 +485,11 @@ class SearchPublicDialogsQuery : public Td::ResultHandler {
td->contacts_manager_->on_get_chats(std::move(dialogs->chats_)); td->contacts_manager_->on_get_chats(std::move(dialogs->chats_));
td->contacts_manager_->on_get_users(std::move(dialogs->users_)); td->contacts_manager_->on_get_users(std::move(dialogs->users_));
td->messages_manager_->on_get_public_dialogs_search_result(query_, std::move(dialogs->results_)); td->messages_manager_->on_get_public_dialogs_search_result(query_, std::move(dialogs->results_));
promise_.set_value(Unit());
} }
void on_error(uint64 id, Status status) override { void on_error(uint64 id, Status status) override {
td->messages_manager_->on_failed_public_dialogs_search(query_);
LOG(ERROR) << "Receive error for SearchPublicDialogsQuery: " << status; LOG(ERROR) << "Receive error for SearchPublicDialogsQuery: " << status;
promise_.set_error(std::move(status)); td->messages_manager_->on_failed_public_dialogs_search(query_, std::move(status));
} }
}; };
@ -6484,6 +6477,12 @@ void MessagesManager::on_get_history(DialogId dialog_id, MessageId from_message_
void MessagesManager::on_get_public_dialogs_search_result(const string &query, void MessagesManager::on_get_public_dialogs_search_result(const string &query,
vector<tl_object_ptr<telegram_api::Peer>> &&peers) { 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);
auto promises = std::move(it->second);
search_public_dialogs_queries_.erase(it);
vector<DialogId> result; vector<DialogId> result;
result.reserve(peers.size()); result.reserve(peers.size());
for (auto &peer : peers) { for (auto &peer : peers) {
@ -6495,10 +6494,24 @@ void MessagesManager::on_get_public_dialogs_search_result(const string &query,
} }
found_public_dialogs_[query] = std::move(result); found_public_dialogs_[query] = std::move(result);
for (auto &promise : promises) {
promise.set_value(Unit());
}
} }
void MessagesManager::on_failed_public_dialogs_search(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);
auto promises = std::move(it->second);
search_public_dialogs_queries_.erase(it);
found_public_dialogs_[query]; // negative cache found_public_dialogs_[query]; // negative cache
for (auto &promise : promises) {
promise.set_error(error.clone());
}
} }
void MessagesManager::on_get_dialog_messages_search_result(DialogId dialog_id, const string &query, void MessagesManager::on_get_dialog_messages_search_result(DialogId dialog_id, const string &query,
@ -10501,11 +10514,21 @@ vector<DialogId> MessagesManager::search_public_dialogs(const string &query, Pro
return it->second; return it->second;
} }
// TODO MultiPromise send_search_public_dialogs_query(query, std::move(promise));
td_->create_handler<SearchPublicDialogsQuery>(std::move(promise))->send(query);
return vector<DialogId>(); return vector<DialogId>();
} }
void MessagesManager::send_search_public_dialogs_query(const string &query, Promise<Unit> &&promise) {
auto &promises = search_public_dialogs_queries_[query];
promises.push_back(std::move(promise));
if (promises.size() != 1) {
// query has already been sent, just wait for the result
return;
}
td_->create_handler<SearchPublicDialogsQuery>()->send(query);
}
std::pair<size_t, vector<DialogId>> MessagesManager::search_dialogs(const string &query, int32 limit, std::pair<size_t, vector<DialogId>> MessagesManager::search_dialogs(const string &query, int32 limit,
Promise<Unit> &&promise) { Promise<Unit> &&promise) {
LOG(INFO) << "Search chats with query \"" << query << "\" and limit " << limit; LOG(INFO) << "Search chats with query \"" << query << "\" and limit " << limit;
@ -11282,7 +11305,7 @@ void MessagesManager::create_dialog(DialogId dialog_id, Promise<Unit> &&promise)
} else { } else {
const Dialog *d = get_dialog_force(dialog_id); const Dialog *d = get_dialog_force(dialog_id);
if (d == nullptr || !d->notification_settings.is_synchronized) { if (d == nullptr || !d->notification_settings.is_synchronized) {
return get_dialog_query(dialog_id, std::move(promise)); return send_get_dialog_query(dialog_id, std::move(promise));
} }
} }
@ -11790,7 +11813,7 @@ tl_object_ptr<td_api::chat> MessagesManager::get_chat_object(const Dialog *d) {
if (!d->notification_settings.is_synchronized && d->dialog_id.get_type() != DialogType::SecretChat && if (!d->notification_settings.is_synchronized && d->dialog_id.get_type() != DialogType::SecretChat &&
have_input_peer(d->dialog_id, AccessRights::Read)) { have_input_peer(d->dialog_id, AccessRights::Read)) {
// asynchronously get dialog from the server // asynchronously get dialog from the server
get_dialog_query(d->dialog_id, Auto()); send_get_dialog_query(d->dialog_id, Auto());
} }
} }
@ -17549,7 +17572,7 @@ void MessagesManager::send_update_new_message(Dialog *d, const Message *m, bool
auto promise = PromiseCreator::lambda([actor_id = actor_id(this), dialog_id = d->dialog_id](Result<Unit> result) { auto promise = PromiseCreator::lambda([actor_id = actor_id(this), dialog_id = d->dialog_id](Result<Unit> result) {
send_closure(actor_id, &MessagesManager::flush_pending_update_new_messages, dialog_id); send_closure(actor_id, &MessagesManager::flush_pending_update_new_messages, dialog_id);
}); });
get_dialog_query(settings_dialog_id, std::move(promise)); // TODO use GetNotifySettingsQuery when possible send_get_dialog_query(settings_dialog_id, std::move(promise)); // TODO use GetNotifySettingsQuery when possible
return; return;
} }
@ -18419,7 +18442,7 @@ DialogId MessagesManager::search_public_dialog(const string &username_to_search,
} else { } else {
const Dialog *d = get_dialog_force(dialog_id); const Dialog *d = get_dialog_force(dialog_id);
if (d == nullptr || !d->notification_settings.is_synchronized) { if (d == nullptr || !d->notification_settings.is_synchronized) {
get_dialog_query(dialog_id, std::move(promise)); send_get_dialog_query(dialog_id, std::move(promise));
return DialogId(); return DialogId();
} }
} }
@ -18440,7 +18463,7 @@ DialogId MessagesManager::search_public_dialog(const string &username_to_search,
return DialogId(); return DialogId();
} }
void MessagesManager::get_dialog_query(DialogId dialog_id, Promise<Unit> &&promise) { void MessagesManager::send_get_dialog_query(DialogId dialog_id, Promise<Unit> &&promise) {
if (td_->auth_manager_->is_bot()) { if (td_->auth_manager_->is_bot()) {
return; return;
} }
@ -18541,7 +18564,7 @@ void MessagesManager::drop_username(const string &username) {
auto dialog_id = it->second.dialog_id; auto dialog_id = it->second.dialog_id;
if (have_input_peer(dialog_id, AccessRights::Read)) { if (have_input_peer(dialog_id, AccessRights::Read)) {
CHECK(dialog_id.get_type() != DialogType::SecretChat); CHECK(dialog_id.get_type() != DialogType::SecretChat);
get_dialog_query(dialog_id, Auto()); send_get_dialog_query(dialog_id, Auto());
} }
resolved_usernames_.erase(it); resolved_usernames_.erase(it);
@ -22084,7 +22107,7 @@ void MessagesManager::force_create_dialog(DialogId dialog_id, const char *source
if (have_input_peer(dialog_id, AccessRights::Read)) { if (have_input_peer(dialog_id, AccessRights::Read)) {
if (dialog_id.get_type() != DialogType::SecretChat && !d->notification_settings.is_synchronized) { if (dialog_id.get_type() != DialogType::SecretChat && !d->notification_settings.is_synchronized) {
// asynchronously preload information about the dialog // asynchronously preload information about the dialog
get_dialog_query(dialog_id, Auto()); send_get_dialog_query(dialog_id, Auto());
} }
} else { } else {
if (!have_dialog_info(dialog_id)) { if (!have_dialog_info(dialog_id)) {

View File

@ -851,7 +851,7 @@ class MessagesManager : public Actor {
vector<tl_object_ptr<telegram_api::Message>> &&messages); vector<tl_object_ptr<telegram_api::Message>> &&messages);
void on_get_public_dialogs_search_result(const string &query, vector<tl_object_ptr<telegram_api::Peer>> &&peers); void on_get_public_dialogs_search_result(const string &query, vector<tl_object_ptr<telegram_api::Peer>> &&peers);
void on_failed_public_dialogs_search(const string &query); void on_failed_public_dialogs_search(const string &query, Status &&error);
void on_get_dialog_messages_search_result(DialogId dialog_id, const string &query, UserId sender_user_id, void on_get_dialog_messages_search_result(DialogId dialog_id, const string &query, UserId sender_user_id,
MessageId from_message_id, int32 offset, int32 limit, MessageId from_message_id, int32 offset, int32 limit,
@ -2121,7 +2121,9 @@ class MessagesManager : public Actor {
void on_get_dialogs_from_database(vector<BufferSlice> &&dialogs, Promise<Unit> &&promise); void on_get_dialogs_from_database(vector<BufferSlice> &&dialogs, Promise<Unit> &&promise);
void get_dialog_query(DialogId dialog_id, Promise<Unit> &&promise); void send_get_dialog_query(DialogId dialog_id, Promise<Unit> &&promise);
void send_search_public_dialogs_query(const string &query, Promise<Unit> &&promise);
vector<DialogId> get_pinned_dialogs() const; vector<DialogId> get_pinned_dialogs() const;
@ -2510,7 +2512,9 @@ class MessagesManager : public Actor {
std::unordered_map<DialogId, vector<std::pair<MessageId, Promise<Unit>>>, DialogIdHash> std::unordered_map<DialogId, vector<std::pair<MessageId, Promise<Unit>>>, DialogIdHash>
postponed_get_message_requests_; postponed_get_message_requests_;
std::unordered_map<string, vector<Promise<Unit>>> search_public_dialogs_queries_;
std::unordered_map<string, vector<DialogId>> found_public_dialogs_; // TODO time bound cache std::unordered_map<string, vector<DialogId>> found_public_dialogs_; // TODO time bound cache
std::unordered_map<UserId, vector<DialogId>, UserIdHash> found_common_dialogs_; // TODO time bound cache std::unordered_map<UserId, vector<DialogId>, UserIdHash> found_common_dialogs_; // TODO time bound cache
std::unordered_map<int64, FullMessageId> get_dialog_message_by_date_results_; std::unordered_map<int64, FullMessageId> get_dialog_message_by_date_results_;