Move user_online_member_dialogs_ to DialogParticipantManager.

This commit is contained in:
levlam 2024-02-19 02:15:05 +03:00
parent 59b1d7a4f6
commit da979c4631
4 changed files with 112 additions and 103 deletions

View File

@ -3183,9 +3183,8 @@ ContactsManager::~ContactsManager() {
Scheduler::instance()->destroy_on_scheduler(
G()->get_gc_scheduler_id(), loaded_from_database_users_, unavailable_user_fulls_, loaded_from_database_chats_,
unavailable_chat_fulls_, loaded_from_database_channels_, unavailable_channel_fulls_,
loaded_from_database_secret_chats_, user_online_member_dialogs_, cached_channel_participants_,
resolved_phone_numbers_, all_imported_contacts_, linked_channel_ids_, restricted_user_ids_,
restricted_channel_ids_);
loaded_from_database_secret_chats_, cached_channel_participants_, resolved_phone_numbers_, all_imported_contacts_,
linked_channel_ids_, restricted_user_ids_, restricted_channel_ids_);
}
void ContactsManager::start_up() {
@ -3246,7 +3245,7 @@ void ContactsManager::on_user_online_timeout(UserId user_id) {
td_api::make_object<td_api::updateUserStatus>(user_id.get(),
get_user_status_object(user_id, u, G()->unix_time())));
update_user_online_member_count(user_id);
td_->dialog_participant_manager_->update_user_online_member_count(user_id);
}
void ContactsManager::on_user_emoji_status_timeout_callback(void *contacts_manager_ptr, int64 user_id_long) {
@ -11184,7 +11183,7 @@ void ContactsManager::update_user(User *u, UserId user_id, bool from_binlog, boo
u->is_status_changed = false;
}
if (u->is_online_status_changed) {
update_user_online_member_count(user_id);
td_->dialog_participant_manager_->update_user_online_member_count(user_id);
u->is_online_status_changed = false;
}
@ -13585,52 +13584,6 @@ void ContactsManager::drop_user_full(UserId user_id) {
td_->group_call_manager_->on_update_dialog_about(DialogId(user_id), user_full->about, true);
}
void ContactsManager::update_user_online_member_count(UserId user_id) {
if (td_->auth_manager_->is_bot()) {
return;
}
auto user_it = user_online_member_dialogs_.find(user_id);
if (user_it == user_online_member_dialogs_.end()) {
return;
}
CHECK(user_it->second != nullptr);
auto &online_member_dialogs = user_it->second->online_member_dialogs_;
auto now = G()->unix_time();
vector<DialogId> expired_dialog_ids;
for (const auto &it : online_member_dialogs) {
auto dialog_id = it.first;
auto time = it.second;
if (time < now - DialogParticipantManager::ONLINE_MEMBER_COUNT_CACHE_EXPIRE_TIME) {
expired_dialog_ids.push_back(dialog_id);
continue;
}
switch (dialog_id.get_type()) {
case DialogType::Chat:
update_chat_online_member_count(dialog_id.get_chat_id(), false);
break;
case DialogType::Channel:
update_channel_online_member_count(dialog_id.get_channel_id(), false);
break;
case DialogType::User:
case DialogType::SecretChat:
case DialogType::None:
UNREACHABLE();
break;
}
}
for (auto &dialog_id : expired_dialog_ids) {
online_member_dialogs.erase(dialog_id);
if (dialog_id.get_type() == DialogType::Channel) {
cached_channel_participants_.erase(dialog_id.get_channel_id());
}
}
if (online_member_dialogs.empty()) {
user_online_member_dialogs_.erase(user_it);
}
}
void ContactsManager::update_chat_online_member_count(ChatId chat_id, bool is_from_server) {
auto chat_full = get_chat_full(chat_id);
if (chat_full != nullptr) {
@ -13639,7 +13592,8 @@ void ContactsManager::update_chat_online_member_count(ChatId chat_id, bool is_fr
}
void ContactsManager::update_chat_online_member_count(const ChatFull *chat_full, ChatId chat_id, bool is_from_server) {
update_dialog_online_member_count(chat_full->participants, DialogId(chat_id), is_from_server);
td_->dialog_participant_manager_->update_dialog_online_member_count(chat_full->participants, DialogId(chat_id),
is_from_server);
}
void ContactsManager::update_channel_online_member_count(ChannelId channel_id, bool is_from_server) {
@ -13652,38 +13606,11 @@ void ContactsManager::update_channel_online_member_count(ChannelId channel_id, b
if (it == cached_channel_participants_.end()) {
return;
}
update_dialog_online_member_count(it->second, DialogId(channel_id), is_from_server);
td_->dialog_participant_manager_->update_dialog_online_member_count(it->second, DialogId(channel_id), is_from_server);
}
void ContactsManager::update_dialog_online_member_count(const vector<DialogParticipant> &participants,
DialogId dialog_id, bool is_from_server) {
if (td_->auth_manager_->is_bot()) {
return;
}
CHECK(dialog_id.is_valid());
int32 online_member_count = 0;
int32 unix_time = G()->unix_time();
for (const auto &participant : participants) {
if (participant.dialog_id_.get_type() != DialogType::User) {
continue;
}
auto user_id = participant.dialog_id_.get_user_id();
if (!is_user_deleted(user_id) && !is_user_bot(user_id)) {
if (is_user_online(user_id, 0, unix_time)) {
online_member_count++;
}
if (is_from_server) {
auto &online_member_dialogs = user_online_member_dialogs_[user_id];
if (online_member_dialogs == nullptr) {
online_member_dialogs = make_unique<UserOnlineMemberDialogs>();
}
online_member_dialogs->online_member_dialogs_[dialog_id] = unix_time;
}
}
}
td_->dialog_participant_manager_->on_update_dialog_online_member_count(dialog_id, online_member_count,
is_from_server);
void ContactsManager::drop_cached_channel_participants(ChannelId channel_id) {
cached_channel_participants_.erase(channel_id);
}
void ContactsManager::on_get_chat_participants(tl_object_ptr<telegram_api::ChatParticipants> &&participants_ptr,

View File

@ -353,6 +353,12 @@ class ContactsManager final : public Actor {
static ChannelId get_unsupported_channel_id();
void update_chat_online_member_count(ChatId chat_id, bool is_from_server);
void update_channel_online_member_count(ChannelId channel_id, bool is_from_server);
void drop_cached_channel_participants(ChannelId channel_id);
void on_update_username_is_active(UserId user_id, string &&username, bool is_active, Promise<Unit> &&promise);
void on_update_active_usernames_order(UserId user_id, vector<string> &&usernames, Promise<Unit> &&promise);
@ -1551,12 +1557,7 @@ class ContactsManager final : public Actor {
void do_invalidate_channel_full(ChannelFull *channel_full, ChannelId channel_id, bool need_drop_slow_mode_delay);
void update_user_online_member_count(UserId user_id);
void update_chat_online_member_count(ChatId chat_id, bool is_from_server);
void update_chat_online_member_count(const ChatFull *chat_full, ChatId chat_id, bool is_from_server);
void update_channel_online_member_count(ChannelId channel_id, bool is_from_server);
void update_dialog_online_member_count(const vector<DialogParticipant> &participants, DialogId dialog_id,
bool is_from_server);
void on_get_chat_empty(telegram_api::chatEmpty &chat, const char *source);
void on_get_chat(telegram_api::chat &chat, const char *source);
@ -1980,11 +1981,6 @@ class ContactsManager final : public Actor {
FlatHashMap<int64, std::pair<vector<UserId>, vector<int32>>> imported_contacts_;
struct UserOnlineMemberDialogs {
FlatHashMap<DialogId, int32, DialogIdHash> online_member_dialogs_; // dialog_id -> time
};
FlatHashMap<UserId, unique_ptr<UserOnlineMemberDialogs>, UserIdHash> user_online_member_dialogs_;
FlatHashMap<ChannelId, vector<DialogParticipant>, ChannelIdHash> cached_channel_participants_;
FlatHashMap<string, UserId> resolved_phone_numbers_;

View File

@ -591,8 +591,8 @@ DialogParticipantManager::DialogParticipantManager(Td *td, ActorShared<> parent)
}
DialogParticipantManager::~DialogParticipantManager() {
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), dialog_administrators_,
channel_participants_);
Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), user_online_member_dialogs_,
dialog_administrators_, channel_participants_);
}
void DialogParticipantManager::tear_down() {
@ -665,7 +665,7 @@ void DialogParticipantManager::on_update_dialog_online_member_count(DialogId dia
}
set_dialog_online_member_count(dialog_id, online_member_count, is_from_server,
"on_update_channel_online_member_count");
"on_update_dialog_online_member_count");
}
void DialogParticipantManager::on_dialog_opened(DialogId dialog_id) {
@ -753,15 +753,80 @@ void DialogParticipantManager::send_update_chat_online_member_count(DialogId dia
td_->dialog_manager_->get_chat_id_object(dialog_id, "updateChatOnlineMemberCount"), online_member_count));
}
void DialogParticipantManager::get_current_state(vector<td_api::object_ptr<td_api::Update>> &updates) const {
for (const auto &it : dialog_online_member_counts_) {
void DialogParticipantManager::update_user_online_member_count(UserId user_id) {
if (td_->auth_manager_->is_bot()) {
return;
}
auto user_it = user_online_member_dialogs_.find(user_id);
if (user_it == user_online_member_dialogs_.end()) {
return;
}
CHECK(user_it->second != nullptr);
auto &online_member_dialogs = user_it->second->online_member_dialogs_;
auto now = G()->unix_time();
vector<DialogId> expired_dialog_ids;
for (const auto &it : online_member_dialogs) {
auto dialog_id = it.first;
if (it.second.is_update_sent && td_->messages_manager_->is_dialog_opened(dialog_id)) {
updates.push_back(td_api::make_object<td_api::updateChatOnlineMemberCount>(
td_->dialog_manager_->get_chat_id_object(dialog_id, "updateChatOnlineMemberCount"),
it.second.online_member_count));
auto time = it.second;
if (time < now - ONLINE_MEMBER_COUNT_CACHE_EXPIRE_TIME) {
expired_dialog_ids.push_back(dialog_id);
continue;
}
switch (dialog_id.get_type()) {
case DialogType::Chat:
td_->contacts_manager_->update_chat_online_member_count(dialog_id.get_chat_id(), false);
break;
case DialogType::Channel:
td_->contacts_manager_->update_channel_online_member_count(dialog_id.get_channel_id(), false);
break;
case DialogType::User:
case DialogType::SecretChat:
case DialogType::None:
UNREACHABLE();
break;
}
}
for (auto &dialog_id : expired_dialog_ids) {
online_member_dialogs.erase(dialog_id);
if (dialog_id.get_type() == DialogType::Channel) {
td_->contacts_manager_->drop_cached_channel_participants(dialog_id.get_channel_id());
}
}
if (online_member_dialogs.empty()) {
user_online_member_dialogs_.erase(user_it);
}
}
void DialogParticipantManager::update_dialog_online_member_count(const vector<DialogParticipant> &participants,
DialogId dialog_id, bool is_from_server) {
if (td_->auth_manager_->is_bot()) {
return;
}
CHECK(dialog_id.is_valid());
int32 online_member_count = 0;
int32 unix_time = G()->unix_time();
for (const auto &participant : participants) {
if (participant.dialog_id_.get_type() != DialogType::User) {
continue;
}
auto user_id = participant.dialog_id_.get_user_id();
if (!td_->contacts_manager_->is_user_deleted(user_id) && !td_->contacts_manager_->is_user_bot(user_id)) {
if (td_->contacts_manager_->is_user_online(user_id, 0, unix_time)) {
online_member_count++;
}
if (is_from_server) {
auto &online_member_dialogs = user_online_member_dialogs_[user_id];
if (online_member_dialogs == nullptr) {
online_member_dialogs = make_unique<UserOnlineMemberDialogs>();
}
online_member_dialogs->online_member_dialogs_[dialog_id] = unix_time;
}
}
}
on_update_dialog_online_member_count(dialog_id, online_member_count, is_from_server);
}
Status DialogParticipantManager::can_manage_dialog_join_requests(DialogId dialog_id) {
@ -1994,4 +2059,15 @@ const DialogParticipant *DialogParticipantManager::get_channel_participant_from_
return nullptr;
}
void DialogParticipantManager::get_current_state(vector<td_api::object_ptr<td_api::Update>> &updates) const {
for (const auto &it : dialog_online_member_counts_) {
auto dialog_id = it.first;
if (it.second.is_update_sent && td_->messages_manager_->is_dialog_opened(dialog_id)) {
updates.push_back(td_api::make_object<td_api::updateChatOnlineMemberCount>(
td_->dialog_manager_->get_chat_id_object(dialog_id, "updateChatOnlineMemberCount"),
it.second.online_member_count));
}
}
}
} // namespace td

View File

@ -37,7 +37,10 @@ class DialogParticipantManager final : public Actor {
DialogParticipantManager &operator=(DialogParticipantManager &&) = delete;
~DialogParticipantManager() final;
static constexpr int32 ONLINE_MEMBER_COUNT_CACHE_EXPIRE_TIME = 30 * 60;
void update_user_online_member_count(UserId user_id);
void update_dialog_online_member_count(const vector<DialogParticipant> &participants, DialogId dialog_id,
bool is_from_server);
void on_update_dialog_online_member_count(DialogId dialog_id, int32 online_member_count, bool is_from_server);
@ -114,12 +117,14 @@ class DialogParticipantManager final : public Actor {
void get_current_state(vector<td_api::object_ptr<td_api::Update>> &updates) const;
private:
void tear_down() final;
static constexpr int32 ONLINE_MEMBER_COUNT_CACHE_EXPIRE_TIME = 30 * 60;
static constexpr int32 ONLINE_MEMBER_COUNT_UPDATE_TIME = 5 * 60;
static constexpr int32 CHANNEL_PARTICIPANT_CACHE_TIME = 1800; // some reasonable limit
void tear_down() final;
static void on_update_dialog_online_member_count_timeout_callback(void *dialog_participant_manager_ptr,
int64 dialog_id_int);
@ -203,6 +208,11 @@ class DialogParticipantManager final : public Actor {
};
FlatHashMap<DialogId, OnlineMemberCountInfo, DialogIdHash> dialog_online_member_counts_;
struct UserOnlineMemberDialogs {
FlatHashMap<DialogId, int32, DialogIdHash> online_member_dialogs_; // dialog_id -> time
};
FlatHashMap<UserId, unique_ptr<UserOnlineMemberDialogs>, UserIdHash> user_online_member_dialogs_;
FlatHashMap<DialogId, vector<DialogAdministrator>, DialogIdHash> dialog_administrators_;
// bot-administrators only