Update member online count from time to time.

GitOrigin-RevId: 8b9e0f4d922a17c0f14755289a25e91b1ab4c6fc
This commit is contained in:
levlam 2019-02-26 18:24:46 +03:00
parent 60e5854fcf
commit f1519230c9
5 changed files with 105 additions and 10 deletions

View File

@ -2380,7 +2380,7 @@ updateChatReplyMarkup chat_id:int53 reply_markup_message_id:int53 = Update;
//@description A chat draft has changed. Be aware that the update may come in the currently opened chat but with old content of the draft. If the user has changed the content of the draft, this update shouldn't be applied @chat_id Chat identifier @draft_message The new draft message; may be null @order New value of the chat order
updateChatDraftMessage chat_id:int53 draft_message:draftMessage order:int64 = Update;
//@description The number of online group members has changed. This update is sent only for currently open chats. There is no guarantee that it will be sent just after the count has changed @chat_id Identifier of the chat @online_member_count New number of online members in the chat
//@description The number of online group members has changed. This update is sent only for currently open chats. There is no guarantee that it will be sent just after the count has changed @chat_id Identifier of the chat @online_member_count New number of online members in the chat, or 0 if unknown
updateChatOnlineMemberCount chat_id:int53 online_member_count:int32 = Update;
//@description A notification was changed @notification_group_id Unique notification group identifier @notification Changed notification

View File

@ -6640,6 +6640,22 @@ void ContactsManager::on_get_chat_full(tl_object_ptr<telegram_api::ChatFull> &&c
td_->messages_manager_->on_update_dialog_notify_settings(DialogId(chat_id), std::move(chat_full->notify_settings_),
"on_get_chat_full");
int32 online_member_count = 0;
int32 time = G()->unix_time();
for (auto &participant : chat->participants) {
auto u = get_user(participant.user_id);
if (u != nullptr) {
int32 was_online = u->was_online;
if (participant.user_id == get_my_id() && my_was_online_local_ != 0) {
was_online = my_was_online_local_;
}
if (was_online > time) {
online_member_count++;
}
}
}
td_->messages_manager_->on_update_dialog_online_member_count(DialogId(chat_id), online_member_count);
update_chat_full(chat, chat_id);
} else {
CHECK(chat_full_ptr->get_id() == telegram_api::channelFull::ID);
@ -6727,7 +6743,7 @@ void ContactsManager::on_get_chat_full(tl_object_ptr<telegram_api::ChatFull> &&c
if ((channel_full->flags_ & CHANNEL_FULL_FLAG_HAS_ONLINE_MEMBER_COUNT) != 0) {
online_member_count = channel_full->online_count_;
}
td_->messages_manager_->on_update_channel_online_member_count(channel_id, online_member_count);
td_->messages_manager_->on_update_dialog_online_member_count(DialogId(channel_id), online_member_count);
for (auto &bot_info : channel_full->bot_info_) {
on_update_bot_info(std::move(bot_info));

View File

@ -438,6 +438,8 @@ class ContactsManager : public Actor {
UserId get_support_user(Promise<Unit> &&promise);
void repair_chat_participants(ChatId chat_id);
void after_get_difference();
void get_current_state(vector<td_api::object_ptr<td_api::Update>> &updates) const;
@ -839,8 +841,6 @@ class ContactsManager : public Actor {
static LinkState get_link_state(tl_object_ptr<telegram_api::ContactLink> &&link);
void repair_chat_participants(ChatId chat_id);
static bool is_valid_username(const string &username);
bool on_update_bot_info(tl_object_ptr<telegram_api::botInfo> &&bot_info);

View File

@ -83,6 +83,38 @@ void dummyUpdate::store(TlStorerToString &s, const char *field_name) const {
s.store_class_end();
}
class GetOnlinesQuery : public Td::ResultHandler {
DialogId dialog_id_;
public:
void send(DialogId dialog_id) {
dialog_id_ = dialog_id;
CHECK(dialog_id.get_type() == DialogType::Channel);
auto input_peer = td->messages_manager_->get_input_peer(dialog_id, AccessRights::Read);
if (input_peer == nullptr) {
return on_error(0, Status::Error(400, "Can't access the chat"));
}
send_query(
G()->net_query_creator().create(create_storer(telegram_api::messages_getOnlines(std::move(input_peer)))));
}
void on_result(uint64 id, BufferSlice packet) override {
auto result_ptr = fetch_result<telegram_api::messages_getOnlines>(packet);
if (result_ptr.is_error()) {
return on_error(id, result_ptr.move_as_error());
}
auto result = result_ptr.move_as_ok();
td->messages_manager_->on_update_dialog_online_member_count(dialog_id_, result->onlines_);
}
void on_error(uint64 id, Status status) override {
td->messages_manager_->on_get_dialog_error(dialog_id_, status, "GetOnlinesQuery");
td->messages_manager_->on_update_dialog_online_member_count(dialog_id_, 0);
}
};
class GetDialogQuery : public Td::ResultHandler {
DialogId dialog_id_;
@ -4087,6 +4119,9 @@ MessagesManager::MessagesManager(Td *td, ActorShared<> parent) : td_(td), parent
active_dialog_action_timeout_.set_callback(on_active_dialog_action_timeout_callback);
active_dialog_action_timeout_.set_callback_data(static_cast<void *>(this));
update_dialog_online_member_count_timeout_.set_callback(on_update_dialog_online_member_count_timeout_callback);
update_dialog_online_member_count_timeout_.set_callback_data(static_cast<void *>(this));
sequence_dispatcher_ = create_actor<MultiSequenceDispatcher>("multi sequence dispatcher");
}
@ -4205,6 +4240,17 @@ void MessagesManager::on_active_dialog_action_timeout_callback(void *messages_ma
DialogId(dialog_id_int));
}
void MessagesManager::on_update_dialog_online_member_count_timeout_callback(void *messages_manager_ptr,
int64 dialog_id_int) {
if (G()->close_flag()) {
return;
}
auto messages_manager = static_cast<MessagesManager *>(messages_manager_ptr);
send_closure_later(messages_manager->actor_id(messages_manager),
&MessagesManager::on_update_dialog_online_member_count_timeout, DialogId(dialog_id_int));
}
BufferSlice MessagesManager::get_dialog_database_value(const Dialog *d) {
// can't use log_event_store, because it tries to parse stored Dialog
LogEventStorerCalcLength storer_calc_length;
@ -5096,15 +5142,20 @@ void MessagesManager::on_update_channel_max_unavailable_message_id(ChannelId cha
"on_update_channel_max_unavailable_message_id");
}
void MessagesManager::on_update_channel_online_member_count(ChannelId channel_id, int32 online_member_count) {
if (!channel_id.is_valid()) {
LOG(ERROR) << "Receive online member count in invalid " << channel_id;
void MessagesManager::on_update_dialog_online_member_count(DialogId dialog_id, int32 online_member_count) {
if (!dialog_id.is_valid()) {
LOG(ERROR) << "Receive online member count in invalid " << dialog_id;
return;
}
DialogId dialog_id(channel_id);
if (is_broadcast_channel(dialog_id)) {
LOG_IF(ERROR, online_member_count != 0) << "Receive online member count in broadcast " << channel_id;
LOG_IF(ERROR, online_member_count != 0)
<< "Receive online member count " << online_member_count << " in a broadcast " << dialog_id;
return;
}
if (online_member_count < 0) {
LOG(ERROR) << "Receive online member count " << online_member_count << " in a " << dialog_id;
return;
}
@ -8474,6 +8525,7 @@ void MessagesManager::set_dialog_online_member_count(DialogId dialog_id, int32 o
return;
}
LOG(INFO) << "Set online member count to " << online_member_count << " in " << dialog_id << " from " << source;
auto &info = dialog_online_member_counts_[dialog_id];
bool need_update = d->is_opened && (!info.is_update_sent || info.online_member_count != online_member_count);
info.online_member_count = online_member_count;
@ -8483,6 +8535,27 @@ void MessagesManager::set_dialog_online_member_count(DialogId dialog_id, int32 o
info.is_update_sent = true;
send_update_chat_online_member_count(dialog_id, online_member_count);
}
if (d->is_opened) {
update_dialog_online_member_count_timeout_.set_timeout_in(dialog_id.get(), ONLINE_MEMBER_COUNT_UPDATE_TIME);
}
}
void MessagesManager::on_update_dialog_online_member_count_timeout(DialogId dialog_id) {
LOG(INFO) << "Expired timeout for online member count for " << dialog_id;
Dialog *d = get_dialog(dialog_id);
CHECK(d != nullptr);
if (!d->is_opened) {
return;
}
if (dialog_id.get_type() == DialogType::Channel && !is_broadcast_channel(dialog_id)) {
td_->create_handler<GetOnlinesQuery>()->send(dialog_id);
return;
}
if (dialog_id.get_type() == DialogType::Chat) {
td_->contacts_manager_->repair_chat_participants(dialog_id.get_chat_id());
return;
}
}
MessageId MessagesManager::get_message_id(const tl_object_ptr<telegram_api::Message> &message_ptr) {
@ -12902,6 +12975,7 @@ void MessagesManager::close_dialog(Dialog *d) {
auto &info = online_count_it->second;
info.is_update_sent = false;
}
update_dialog_online_member_count_timeout_.cancel_timeout(d->dialog_id.get());
}
}

View File

@ -303,7 +303,7 @@ class MessagesManager : public Actor {
void on_update_channel_max_unavailable_message_id(ChannelId channel_id, MessageId max_unavailable_message_id);
void on_update_channel_online_member_count(ChannelId channel_id, int32 online_member_count);
void on_update_dialog_online_member_count(DialogId dialog_id, int32 online_member_count);
void on_update_include_sponsored_dialog_to_unread_count();
@ -1461,6 +1461,8 @@ class MessagesManager : public Actor {
void set_dialog_online_member_count(DialogId dialog_id, int32 online_member_count, const char *source);
void on_update_dialog_online_member_count_timeout(DialogId dialog_id);
void preload_newer_messages(const Dialog *d, MessageId max_message_id);
void preload_older_messages(const Dialog *d, MessageId min_message_id);
@ -1985,6 +1987,8 @@ class MessagesManager : public Actor {
static void on_active_dialog_action_timeout_callback(void *messages_manager_ptr, int64 dialog_id_int);
static void on_update_dialog_online_member_count_timeout_callback(void *messages_manager_ptr, int64 dialog_id_int);
void load_secret_thumbnail(FileId thumbnail_file_id);
static tl_object_ptr<telegram_api::channelAdminLogEventsFilter> get_channel_admin_log_events_filter(
@ -2298,6 +2302,7 @@ class MessagesManager : public Actor {
MultiTimeout dialog_unmute_timeout_{"DialogUnmuteTimeout"};
MultiTimeout pending_send_dialog_action_timeout_{"PendingSendDialogActionTimeout"};
MultiTimeout active_dialog_action_timeout_{"ActiveDialogActionTimeout"};
MultiTimeout update_dialog_online_member_count_timeout_{"UpdateDialogOnlineMemberCountTimeout"};
Hints dialogs_hints_; // search dialogs by title and username