Replace GetChatMemberRequest with REQUEST_PROMISE.

This commit is contained in:
levlam 2021-07-19 04:17:29 +03:00
parent 4caf74a86f
commit 13fcffd711
3 changed files with 117 additions and 141 deletions

View File

@ -14658,68 +14658,81 @@ void ContactsManager::ban_dialog_participant(DialogId dialog_id,
}
}
DialogParticipant ContactsManager::get_dialog_participant(DialogId dialog_id,
const tl_object_ptr<td_api::MessageSender> &participant_id,
int64 &random_id, bool force, Promise<Unit> &&promise) {
// TODO TRY_RESULT_PROMISE(promise, participant_dialog_id, get_participant_dialog_id(participant_id));
auto r_participant_dialog_id = get_participant_dialog_id(participant_id);
if (r_participant_dialog_id.is_error()) {
promise.set_error(r_participant_dialog_id.move_as_error());
return {};
}
auto participant_dialog_id = r_participant_dialog_id.move_as_ok();
void ContactsManager::get_dialog_participant(DialogId dialog_id,
const tl_object_ptr<td_api::MessageSender> &participant_id,
Promise<td_api::object_ptr<td_api::chatMember>> &&promise) {
TRY_RESULT_PROMISE(promise, participant_dialog_id, get_participant_dialog_id(participant_id));
LOG(INFO) << "Receive GetChatMember request to get " << participant_dialog_id << " in " << dialog_id
<< " with random_id " << random_id;
auto new_promise = PromiseCreator::lambda(
[actor_id = actor_id(this), promise = std::move(promise)](Result<DialogParticipant> &&result) mutable {
TRY_RESULT_PROMISE(promise, dialog_participant, std::move(result));
send_closure(actor_id, &ContactsManager::finish_get_dialog_participant, std::move(dialog_participant),
std::move(promise));
});
get_dialog_participant(dialog_id, participant_dialog_id, std::move(new_promise));
}
void ContactsManager::finish_get_dialog_participant(DialogParticipant &&dialog_participant,
Promise<td_api::object_ptr<td_api::chatMember>> &&promise) {
if (G()->close_flag()) {
return promise.set_error(Status::Error(500, "Request aborted"));
}
auto participant_dialog_id = dialog_participant.dialog_id;
bool is_user = participant_dialog_id.get_type() == DialogType::User;
if ((is_user && !have_user(participant_dialog_id.get_user_id())) ||
(!is_user && !td_->messages_manager_->have_dialog(participant_dialog_id))) {
return promise.set_error(Status::Error(400, "Member not found"));
}
promise.set_value(get_chat_member_object(dialog_participant));
}
void ContactsManager::get_dialog_participant(DialogId dialog_id, DialogId participant_dialog_id,
Promise<DialogParticipant> &&promise) {
LOG(INFO) << "Receive GetChatMember request to get " << participant_dialog_id << " in " << dialog_id;
if (!td_->messages_manager_->have_dialog_force(dialog_id, "get_dialog_participant")) {
promise.set_error(Status::Error(3, "Chat not found"));
return DialogParticipant();
return promise.set_error(Status::Error(3, "Chat not found"));
}
switch (dialog_id.get_type()) {
case DialogType::User:
if (participant_dialog_id == DialogId(get_my_id())) {
promise.set_value(Unit());
return {participant_dialog_id, dialog_id.get_user_id(), 0, DialogParticipantStatus::Member()};
return promise.set_value(
DialogParticipant{participant_dialog_id, dialog_id.get_user_id(), 0, DialogParticipantStatus::Member()});
}
if (participant_dialog_id == dialog_id) {
promise.set_value(Unit());
return {participant_dialog_id, get_my_id(), 0, DialogParticipantStatus::Member()};
return promise.set_value(
DialogParticipant{participant_dialog_id, get_my_id(), 0, DialogParticipantStatus::Member()});
}
promise.set_error(Status::Error(3, "Member not found"));
break;
return promise.set_error(Status::Error(3, "Member not found"));
case DialogType::Chat:
if (participant_dialog_id.get_type() != DialogType::User) {
promise.set_value(Unit());
return DialogParticipant::left(participant_dialog_id);
return promise.set_value(DialogParticipant::left(participant_dialog_id));
}
return get_chat_participant(dialog_id.get_chat_id(), participant_dialog_id.get_user_id(), force,
std::move(promise));
return get_chat_participant(dialog_id.get_chat_id(), participant_dialog_id.get_user_id(), std::move(promise));
case DialogType::Channel:
return get_channel_participant(dialog_id.get_channel_id(), participant_dialog_id, random_id, force,
std::move(promise));
return get_channel_participant(dialog_id.get_channel_id(), participant_dialog_id, std::move(promise));
case DialogType::SecretChat: {
auto peer_user_id = get_secret_chat_user_id(dialog_id.get_secret_chat_id());
if (participant_dialog_id == DialogId(get_my_id())) {
promise.set_value(Unit());
return {participant_dialog_id, peer_user_id.is_valid() ? peer_user_id : get_my_id(), 0,
DialogParticipantStatus::Member()};
return promise.set_value(DialogParticipant{participant_dialog_id,
peer_user_id.is_valid() ? peer_user_id : get_my_id(), 0,
DialogParticipantStatus::Member()});
}
if (participant_dialog_id == DialogId(peer_user_id)) {
promise.set_value(Unit());
return {participant_dialog_id, get_my_id(), 0, DialogParticipantStatus::Member()};
return promise.set_value(
DialogParticipant{participant_dialog_id, get_my_id(), 0, DialogParticipantStatus::Member()});
}
promise.set_error(Status::Error(3, "Member not found"));
break;
return promise.set_error(Status::Error(3, "Member not found"));
}
case DialogType::None:
default:
UNREACHABLE();
promise.set_error(Status::Error(500, "Wrong chat type"));
return promise.set_error(Status::Error(500, "Wrong chat type"));
}
return DialogParticipant();
}
DialogParticipants ContactsManager::search_private_chat_participants(UserId my_user_id, UserId peer_user_id,
@ -14846,22 +14859,43 @@ void ContactsManager::search_dialog_participants(DialogId dialog_id, const strin
}
}
DialogParticipant ContactsManager::get_chat_participant(ChatId chat_id, UserId user_id, bool force,
Promise<Unit> &&promise) {
void ContactsManager::get_chat_participant(ChatId chat_id, UserId user_id, Promise<DialogParticipant> &&promise) {
LOG(INFO) << "Trying to get " << user_id << " as member of " << chat_id;
if (force) {
promise.set_value(Unit());
} else if (!load_chat_full(chat_id, force, std::move(promise), "get_chat_participant")) {
return DialogParticipant();
}
// promise is already set
auto result = get_chat_participant(chat_id, user_id);
if (result == nullptr) {
return DialogParticipant::left(DialogId(user_id));
auto c = get_chat(chat_id);
if (c == nullptr) {
return promise.set_error(Status::Error(6, "Group not found"));
}
return *result;
auto chat_full = get_chat_full_force(chat_id, "get_chat_participant");
if (chat_full == nullptr || (td_->auth_manager_->is_bot() && is_chat_full_outdated(chat_full, c, chat_id))) {
auto query_promise = PromiseCreator::lambda(
[actor_id = actor_id(this), chat_id, user_id, promise = std::move(promise)](Result<Unit> &&result) mutable {
TRY_STATUS_PROMISE(promise, std::move(result));
send_closure(actor_id, &ContactsManager::finish_get_chat_participant, chat_id, user_id, std::move(promise));
});
send_get_chat_full_query(chat_id, std::move(query_promise), "get_chat_participant");
}
if (is_chat_full_outdated(chat_full, c, chat_id)) {
send_get_chat_full_query(chat_id, Auto(), "get_chat_participant lazy");
}
finish_get_chat_participant(chat_id, user_id, std::move(promise));
}
void ContactsManager::finish_get_chat_participant(ChatId chat_id, UserId user_id,
Promise<DialogParticipant> &&promise) {
if (G()->close_flag()) {
return promise.set_error(Status::Error(500, "Request aborted"));
}
const auto *participant = get_chat_participant(chat_id, user_id);
if (participant == nullptr) {
return promise.set_value(DialogParticipant::left(DialogId(user_id)));
}
promise.set_value(DialogParticipant(*participant));
}
void ContactsManager::search_chat_participants(ChatId chat_id, const string &query, int32 limit,
@ -14931,77 +14965,46 @@ void ContactsManager::do_search_chat_participants(ChatId chat_id, const string &
})});
}
DialogParticipant ContactsManager::get_channel_participant(ChannelId channel_id, DialogId participant_dialog_id,
int64 &random_id, bool force, Promise<Unit> &&promise) {
LOG(INFO) << "Trying to get " << participant_dialog_id << " as member of " << channel_id << " with random_id "
<< random_id;
if (random_id != 0) {
// request has already been sent before
auto it = received_channel_participant_.find(random_id);
CHECK(it != received_channel_participant_.end());
auto result = std::move(it->second);
result.status.update_restrictions();
received_channel_participant_.erase(it);
promise.set_value(Unit());
return result;
}
void ContactsManager::get_channel_participant(ChannelId channel_id, DialogId participant_dialog_id,
Promise<DialogParticipant> &&promise) {
LOG(INFO) << "Trying to get " << participant_dialog_id << " as member of " << channel_id;
auto input_peer = td_->messages_manager_->get_input_peer(participant_dialog_id, AccessRights::Read);
if (input_peer == nullptr) {
promise.set_error(Status::Error(6, "User not found"));
return DialogParticipant();
return promise.set_error(Status::Error(6, "User not found"));
}
if (have_channel_participant_cache(channel_id)) {
auto *participant = get_channel_participant_from_cache(channel_id, participant_dialog_id);
if (participant != nullptr) {
promise.set_value(Unit());
return *participant;
return promise.set_value(DialogParticipant{*participant});
}
}
do {
random_id = Random::secure_int64();
} while (random_id == 0 || received_channel_participant_.find(random_id) != received_channel_participant_.end());
received_channel_participant_[random_id]; // reserve place for result
LOG(DEBUG) << "Get info about " << participant_dialog_id << " membership in the " << channel_id << " with random_id "
<< random_id;
auto on_result_promise =
PromiseCreator::lambda([actor_id = actor_id(this), channel_id, random_id,
promise = std::move(promise)](Result<DialogParticipant> r_dialog_participant) mutable {
send_closure(actor_id, &ContactsManager::on_get_channel_participant, channel_id, random_id,
std::move(r_dialog_participant), std::move(promise));
});
auto on_result_promise = PromiseCreator::lambda([actor_id = actor_id(this), channel_id, promise = std::move(promise)](
Result<DialogParticipant> r_dialog_participant) mutable {
TRY_RESULT_PROMISE(promise, dialog_participant, std::move(r_dialog_participant));
send_closure(actor_id, &ContactsManager::finish_get_channel_participant, channel_id, std::move(dialog_participant),
std::move(promise));
});
td_->create_handler<GetChannelParticipantQuery>(std::move(on_result_promise))
->send(channel_id, participant_dialog_id, std::move(input_peer));
return DialogParticipant();
}
void ContactsManager::on_get_channel_participant(ChannelId channel_id, int64 random_id,
Result<DialogParticipant> r_dialog_participant,
Promise<Unit> &&promise) {
void ContactsManager::finish_get_channel_participant(ChannelId channel_id, DialogParticipant &&dialog_participant,
Promise<DialogParticipant> &&promise) {
if (G()->close_flag()) {
return promise.set_error(Status::Error(500, "Request aborted"));
}
LOG(INFO) << "Receive a member of a channel " << channel_id << " with random_id " << random_id;
LOG(INFO) << "Receive a member " << dialog_participant.dialog_id << " of a channel " << channel_id;
auto it = received_channel_participant_.find(random_id);
CHECK(it != received_channel_participant_.end());
if (r_dialog_participant.is_error()) {
received_channel_participant_.erase(it);
promise.set_error(r_dialog_participant.move_as_error());
} else {
it->second = r_dialog_participant.move_as_ok();
if (have_channel_participant_cache(channel_id)) {
add_channel_participant_to_cache(channel_id, it->second, false);
}
promise.set_value(Unit());
dialog_participant.status.update_restrictions();
if (have_channel_participant_cache(channel_id)) {
add_channel_participant_to_cache(channel_id, dialog_participant, false);
}
promise.set_value(std::move(dialog_participant));
}
void ContactsManager::get_channel_participants(ChannelId channel_id,

View File

@ -520,9 +520,8 @@ class ContactsManager final : public Actor {
void ban_dialog_participant(DialogId dialog_id, const tl_object_ptr<td_api::MessageSender> &participant_id,
int32 banned_until_date, bool revoke_messages, Promise<Unit> &&promise);
DialogParticipant get_dialog_participant(DialogId dialog_id,
const tl_object_ptr<td_api::MessageSender> &participant_id, int64 &random_id,
bool force, Promise<Unit> &&promise);
void get_dialog_participant(DialogId dialog_id, const tl_object_ptr<td_api::MessageSender> &participant_id,
Promise<td_api::object_ptr<td_api::chatMember>> &&promise);
void search_dialog_participants(DialogId dialog_id, const string &query, int32 limit, DialogParticipantsFilter filter,
Promise<DialogParticipants> &&promise);
@ -1408,10 +1407,20 @@ class ContactsManager final : public Actor {
DialogParticipants search_private_chat_participants(UserId my_user_id, UserId peer_user_id, const string &query,
int32 limit, DialogParticipantsFilter filter) const;
DialogParticipant get_chat_participant(ChatId chat_id, UserId user_id, bool force, Promise<Unit> &&promise);
void get_dialog_participant(DialogId dialog_id, DialogId participant_dialog_id, Promise<DialogParticipant> &&promise);
DialogParticipant get_channel_participant(ChannelId channel_id, DialogId participant_dialog_id, int64 &random_id,
bool force, Promise<Unit> &&promise);
void finish_get_dialog_participant(DialogParticipant &&dialog_participant,
Promise<td_api::object_ptr<td_api::chatMember>> &&promise);
void get_chat_participant(ChatId chat_id, UserId user_id, Promise<DialogParticipant> &&promise);
void finish_get_chat_participant(ChatId chat_id, UserId user_id, Promise<DialogParticipant> &&promise);
void get_channel_participant(ChannelId channel_id, DialogId participant_dialog_id,
Promise<DialogParticipant> &&promise);
void finish_get_channel_participant(ChannelId channel_id, DialogParticipant &&dialog_participant,
Promise<DialogParticipant> &&promise);
static string get_dialog_administrators_database_key(DialogId dialog_id);
@ -1474,9 +1483,6 @@ class ContactsManager final : public Actor {
void delete_chat_participant(ChatId chat_id, UserId user_id, bool revoke_messages, Promise<Unit> &&promise);
void on_get_channel_participant(ChannelId channel_id, int64 random_id, Result<DialogParticipant> r_dialog_participant,
Promise<Unit> &&promise);
void search_chat_participants(ChatId chat_id, const string &query, int32 limit, DialogParticipantsFilter filter,
Promise<DialogParticipants> &&promise);
@ -1649,8 +1655,6 @@ class ContactsManager final : public Actor {
std::unordered_map<int64, std::pair<vector<UserId>, vector<int32>>> imported_contacts_;
std::unordered_map<int64, DialogParticipant> received_channel_participant_;
std::unordered_map<ChannelId, vector<DialogParticipant>, ChannelIdHash> cached_channel_participants_;
// bot-administrators only

View File

@ -1943,39 +1943,6 @@ class UpgradeGroupChatToSupergroupChatRequest final : public RequestActor<> {
}
};
class GetChatMemberRequest final : public RequestActor<> {
DialogId dialog_id_;
tl_object_ptr<td_api::MessageSender> participant_id_;
int64 random_id_;
DialogParticipant dialog_participant_;
void do_run(Promise<Unit> &&promise) final {
dialog_participant_ = td->contacts_manager_->get_dialog_participant(dialog_id_, participant_id_, random_id_,
get_tries() < 3, std::move(promise));
}
void do_send_result() final {
auto participant_dialog_id = dialog_participant_.dialog_id;
bool is_user = participant_dialog_id.get_type() == DialogType::User;
if ((is_user && !td->contacts_manager_->have_user(participant_dialog_id.get_user_id())) ||
(!is_user && !td->messages_manager_->have_dialog(participant_dialog_id))) {
return send_error(Status::Error(3, "Member not found"));
}
send_result(td->contacts_manager_->get_chat_member_object(dialog_participant_));
}
public:
GetChatMemberRequest(ActorShared<Td> td, uint64 request_id, int64 dialog_id,
tl_object_ptr<td_api::MessageSender> participant_id)
: RequestActor(std::move(td), request_id)
, dialog_id_(dialog_id)
, participant_id_(std::move(participant_id))
, random_id_(0) {
set_tries(3);
}
};
class GetChatAdministratorsRequest final : public RequestActor<> {
DialogId dialog_id_;
@ -6491,7 +6458,9 @@ void Td::on_request(uint64 id, td_api::transferChatOwnership &request) {
}
void Td::on_request(uint64 id, td_api::getChatMember &request) {
CREATE_REQUEST(GetChatMemberRequest, request.chat_id_, std::move(request.member_id_));
CREATE_REQUEST_PROMISE();
contacts_manager_->get_dialog_participant(DialogId(request.chat_id_), std::move(request.member_id_),
std::move(promise));
}
void Td::on_request(uint64 id, td_api::searchChatMembers &request) {