Add disable_top_chats option.
GitOrigin-RevId: 732ba115f67d19585b4e2f4aae024194c6e65174
This commit is contained in:
parent
46535703e0
commit
7150cfc8b2
@ -5,6 +5,7 @@
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
#pragma once
|
||||
|
||||
#include "td/mtproto/utils.h"
|
||||
|
||||
#include "td/utils/common.h"
|
||||
@ -234,5 +235,6 @@ class Transport {
|
||||
static void write_crypto_impl(int X, const Storer &storer, const AuthKey &auth_key, PacketInfo *info, HeaderT *header,
|
||||
size_t data_size);
|
||||
};
|
||||
|
||||
} // namespace mtproto
|
||||
} // namespace td
|
||||
|
@ -4262,9 +4262,13 @@ void Td::on_config_option_updated(const string &name) {
|
||||
send_closure(storage_manager_, &StorageManager::update_use_storage_optimizer);
|
||||
} else if (name == "rating_e_decay") {
|
||||
return send_closure(top_dialog_manager_, &TopDialogManager::update_rating_e_decay);
|
||||
} else if (name == "disable_top_chats") {
|
||||
send_closure(top_dialog_manager_, &TopDialogManager::update_is_enabled,
|
||||
!G()->shared_config().get_option_boolean(name));
|
||||
} else if (is_internal_config_option(name)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// send_closure was already used in the callback
|
||||
send_update(make_tl_object<td_api::updateOption>(name, G()->shared_config().get_option_value(name)));
|
||||
}
|
||||
@ -6682,6 +6686,9 @@ void Td::on_request(uint64 id, td_api::setOption &request) {
|
||||
if (set_boolean_option("disable_contact_registered_notifications")) {
|
||||
return;
|
||||
}
|
||||
if (set_boolean_option("disable_top_chats")) {
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case 'i':
|
||||
if (set_boolean_option("ignore_inline_thumbnails")) {
|
||||
|
@ -90,8 +90,42 @@ static tl_object_ptr<telegram_api::TopPeerCategory> top_dialog_category_as_teleg
|
||||
}
|
||||
}
|
||||
|
||||
void TopDialogManager::update_is_enabled(bool is_enabled) {
|
||||
if (set_is_enabled(is_enabled)) {
|
||||
G()->td_db()->get_binlog_pmc()->set("top_peers_enabled", is_enabled ? "1" : "0");
|
||||
send_toggle_top_peers(is_enabled);
|
||||
|
||||
loop();
|
||||
}
|
||||
}
|
||||
|
||||
bool TopDialogManager::set_is_enabled(bool is_enabled) {
|
||||
if (is_enabled_ == is_enabled) {
|
||||
return false;
|
||||
}
|
||||
|
||||
LOG(DEBUG) << "Change top chats is_enabled to " << is_enabled;
|
||||
is_enabled_ = is_enabled;
|
||||
init();
|
||||
return true;
|
||||
}
|
||||
|
||||
void TopDialogManager::send_toggle_top_peers(bool is_enabled) {
|
||||
if (have_toggle_top_peers_query_) {
|
||||
have_pending_toggle_top_peers_query_ = true;
|
||||
pending_toggle_top_peers_query_ = is_enabled;
|
||||
return;
|
||||
}
|
||||
|
||||
LOG(DEBUG) << "Send toggle top peers query to " << is_enabled;
|
||||
have_toggle_top_peers_query_ = true;
|
||||
toggle_top_peers_query_is_enabled_ = is_enabled;
|
||||
auto net_query = G()->net_query_creator().create(create_storer(telegram_api::contacts_toggleTopPeers(is_enabled)));
|
||||
G()->net_query_dispatcher().dispatch_with_callback(std::move(net_query), actor_shared(this, 2));
|
||||
}
|
||||
|
||||
void TopDialogManager::on_dialog_used(TopDialogCategory category, DialogId dialog_id, int32 date) {
|
||||
if (!is_active_) {
|
||||
if (!is_active_ || !is_enabled_) {
|
||||
return;
|
||||
}
|
||||
auto pos = static_cast<size_t>(category);
|
||||
@ -129,7 +163,7 @@ void TopDialogManager::on_dialog_used(TopDialogCategory category, DialogId dialo
|
||||
|
||||
void TopDialogManager::remove_dialog(TopDialogCategory category, DialogId dialog_id,
|
||||
tl_object_ptr<telegram_api::InputPeer> input_peer) {
|
||||
if (!is_active_) {
|
||||
if (!is_active_ || !is_enabled_) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -165,6 +199,11 @@ void TopDialogManager::get_top_dialogs(TopDialogCategory category, size_t limit,
|
||||
promise.set_error(Status::Error(400, "Not supported without chat info database"));
|
||||
return;
|
||||
}
|
||||
if (!is_enabled_) {
|
||||
promise.set_error(Status::Error(400, "Top chats computation is disabled"));
|
||||
return;
|
||||
}
|
||||
|
||||
GetTopDialogsQuery query;
|
||||
query.category = category;
|
||||
query.limit = limit;
|
||||
@ -302,33 +341,66 @@ void TopDialogManager::do_get_top_peers() {
|
||||
}
|
||||
|
||||
void TopDialogManager::on_result(NetQueryPtr net_query) {
|
||||
if (get_link_token() == 1) {
|
||||
auto query_type = get_link_token();
|
||||
if (query_type == 2) { // toggleTopPeers
|
||||
CHECK(have_toggle_top_peers_query_);
|
||||
have_toggle_top_peers_query_ = false;
|
||||
|
||||
if (have_pending_toggle_top_peers_query_) {
|
||||
have_pending_toggle_top_peers_query_ = false;
|
||||
if (pending_toggle_top_peers_query_ != toggle_top_peers_query_is_enabled_) {
|
||||
send_toggle_top_peers(pending_toggle_top_peers_query_);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
auto r_result = fetch_result<telegram_api::contacts_toggleTopPeers>(std::move(net_query));
|
||||
if (r_result.is_ok()) {
|
||||
// everything is synchronized
|
||||
G()->td_db()->get_binlog_pmc()->erase("top_peers_enabled");
|
||||
} else {
|
||||
// let's resend the query forever
|
||||
if (!G()->close_flag()) {
|
||||
send_toggle_top_peers(toggle_top_peers_query_is_enabled_);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (query_type == 1) { // resetTopPeerRating
|
||||
// ignore result
|
||||
return;
|
||||
}
|
||||
SCOPE_EXIT {
|
||||
loop();
|
||||
};
|
||||
|
||||
normalize_rating(); // once a day too
|
||||
last_server_sync_ = Timestamp::now();
|
||||
server_sync_state_ = SyncState::Ok;
|
||||
G()->td_db()->get_binlog_pmc()->set("top_dialogs_ts", to_string(static_cast<uint32>(Clocks::system())));
|
||||
|
||||
auto r_top_peers = fetch_result<telegram_api::contacts_getTopPeers>(std::move(net_query));
|
||||
if (r_top_peers.is_error()) {
|
||||
LOG(ERROR) << "contacts_getTopPeers failed: " << r_top_peers.error();
|
||||
return;
|
||||
}
|
||||
auto top_peers_parent = r_top_peers.move_as_ok();
|
||||
LOG(INFO) << "contacts_getTopPeers returned " << to_string(top_peers_parent);
|
||||
if (top_peers_parent->get_id() == telegram_api::contacts_topPeersNotModified::ID) {
|
||||
return;
|
||||
}
|
||||
if (top_peers_parent->get_id() == telegram_api::contacts_topPeersDisabled::ID) {
|
||||
// FIXME
|
||||
last_server_sync_ = Timestamp::in(SERVER_SYNC_RESEND_DELAY - SERVER_SYNC_DELAY);
|
||||
return;
|
||||
}
|
||||
|
||||
CHECK(top_peers_parent->get_id() == telegram_api::contacts_topPeers::ID);
|
||||
last_server_sync_ = Timestamp::now();
|
||||
server_sync_state_ = SyncState::Ok;
|
||||
SCOPE_EXIT {
|
||||
G()->td_db()->get_binlog_pmc()->set("top_dialogs_ts", to_string(static_cast<uint32>(Clocks::system())));
|
||||
};
|
||||
|
||||
auto top_peers_parent = r_top_peers.move_as_ok();
|
||||
LOG(DEBUG) << "contacts_getTopPeers returned " << to_string(top_peers_parent);
|
||||
switch (top_peers_parent->get_id()) {
|
||||
case telegram_api::contacts_topPeersNotModified::ID:
|
||||
// nothing to do
|
||||
return;
|
||||
case telegram_api::contacts_topPeersDisabled::ID:
|
||||
G()->shared_config().set_option_boolean("disable_top_chats", true);
|
||||
set_is_enabled(false); // apply immediately
|
||||
return;
|
||||
case telegram_api::contacts_topPeers::ID: {
|
||||
G()->shared_config().set_option_empty("disable_top_chats");
|
||||
set_is_enabled(true); // apply immediately
|
||||
auto top_peers = move_tl_object_as<telegram_api::contacts_topPeers>(std::move(top_peers_parent));
|
||||
|
||||
send_closure(G()->contacts_manager(), &ContactsManager::on_get_users, std::move(top_peers->users_));
|
||||
@ -349,6 +421,11 @@ void TopDialogManager::on_result(NetQueryPtr net_query) {
|
||||
}
|
||||
}
|
||||
db_sync_state_ = SyncState::None;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
|
||||
void TopDialogManager::do_save_top_dialogs() {
|
||||
@ -370,12 +447,31 @@ void TopDialogManager::do_save_top_dialogs() {
|
||||
}
|
||||
|
||||
void TopDialogManager::start_up() {
|
||||
if (!G()->parameters().use_chat_info_db) {
|
||||
is_active_ = G()->parameters().use_chat_info_db;
|
||||
is_enabled_ = !G()->shared_config().get_option_boolean("disable_top_chats");
|
||||
update_rating_e_decay();
|
||||
|
||||
string need_update_top_peers = G()->td_db()->get_binlog_pmc()->get("top_peers_enabled");
|
||||
if (!need_update_top_peers.empty()) {
|
||||
send_toggle_top_peers(need_update_top_peers[0] == '1');
|
||||
}
|
||||
|
||||
init();
|
||||
loop();
|
||||
}
|
||||
|
||||
void TopDialogManager::init() {
|
||||
was_first_sync_ = false;
|
||||
first_unsync_change_ = Timestamp();
|
||||
server_sync_state_ = SyncState::None;
|
||||
last_server_sync_ = Timestamp();
|
||||
CHECK(pending_get_top_dialogs_.empty());
|
||||
|
||||
LOG(DEBUG) << "Init is enabled: " << is_enabled_;
|
||||
if (!is_active_) {
|
||||
G()->td_db()->get_binlog_pmc()->erase_by_prefix("top_dialogs");
|
||||
is_active_ = false;
|
||||
return;
|
||||
}
|
||||
is_active_ = true;
|
||||
|
||||
auto di_top_dialogs_ts = G()->td_db()->get_binlog_pmc()->get("top_dialogs_ts");
|
||||
if (!di_top_dialogs_ts.empty()) {
|
||||
@ -384,8 +480,8 @@ void TopDialogManager::start_up() {
|
||||
server_sync_state_ = SyncState::Ok;
|
||||
}
|
||||
}
|
||||
update_rating_e_decay();
|
||||
|
||||
if (is_enabled_) {
|
||||
for (size_t top_dialog_category_i = 0; top_dialog_category_i < by_category_.size(); top_dialog_category_i++) {
|
||||
auto top_dialog_category = TopDialogCategory(top_dialog_category_i);
|
||||
auto key = PSTRING() << "top_dialogs#" << top_dialog_category_name(top_dialog_category);
|
||||
@ -399,12 +495,18 @@ void TopDialogManager::start_up() {
|
||||
log_event_parse(top_dialogs, value).ensure();
|
||||
}
|
||||
normalize_rating();
|
||||
} else {
|
||||
G()->td_db()->get_binlog_pmc()->erase_by_prefix("top_dialogs#");
|
||||
for (auto &top_dialogs : by_category_) {
|
||||
top_dialogs.is_dirty = false;
|
||||
top_dialogs.rating_timestamp = 0;
|
||||
top_dialogs.dialogs.clear();
|
||||
}
|
||||
}
|
||||
db_sync_state_ = SyncState::Ok;
|
||||
|
||||
send_closure(G()->state_manager(), &StateManager::wait_first_sync,
|
||||
PromiseCreator::event(self_closure(this, &TopDialogManager::on_first_sync)));
|
||||
|
||||
loop();
|
||||
}
|
||||
|
||||
void TopDialogManager::on_first_sync() {
|
||||
@ -441,6 +543,7 @@ void TopDialogManager::loop() {
|
||||
do_get_top_peers();
|
||||
}
|
||||
|
||||
if (is_enabled_) {
|
||||
// db sync
|
||||
Timestamp db_sync_timeout;
|
||||
if (db_sync_state_ == SyncState::Ok) {
|
||||
@ -459,6 +562,7 @@ void TopDialogManager::loop() {
|
||||
do_save_top_dialogs();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (wakeup_timeout) {
|
||||
LOG(INFO) << "Wakeup in: " << wakeup_timeout.in();
|
||||
|
@ -57,13 +57,23 @@ class TopDialogManager : public NetQueryCallback {
|
||||
|
||||
void update_rating_e_decay();
|
||||
|
||||
void update_is_enabled(bool is_enabled);
|
||||
|
||||
private:
|
||||
static constexpr size_t MAX_TOP_DIALOGS_LIMIT = 30;
|
||||
static constexpr int32 SERVER_SYNC_DELAY = 86400; // seconds
|
||||
static constexpr int32 SERVER_SYNC_RESEND_DELAY = 60; // seconds
|
||||
static constexpr int32 DB_SYNC_DELAY = 5; // seconds
|
||||
ActorShared<> parent_;
|
||||
|
||||
bool is_active_{false};
|
||||
bool is_enabled_{true};
|
||||
int32 rating_e_decay_ = 241920;
|
||||
|
||||
bool have_toggle_top_peers_query_ = false;
|
||||
bool toggle_top_peers_query_is_enabled_ = false;
|
||||
bool have_pending_toggle_top_peers_query_ = false;
|
||||
bool pending_toggle_top_peers_query_ = false;
|
||||
bool was_first_sync_{false};
|
||||
enum class SyncState : int32 { None, Pending, Ok };
|
||||
SyncState db_sync_state_ = SyncState::None;
|
||||
@ -106,7 +116,8 @@ class TopDialogManager : public NetQueryCallback {
|
||||
double current_rating_add(double rating_timestamp) const;
|
||||
void normalize_rating();
|
||||
|
||||
int32 rating_e_decay_ = 241920;
|
||||
bool set_is_enabled(bool is_enabled);
|
||||
void send_toggle_top_peers(bool is_enabled);
|
||||
|
||||
void do_get_top_dialogs(GetTopDialogsQuery &&query);
|
||||
|
||||
@ -117,6 +128,8 @@ class TopDialogManager : public NetQueryCallback {
|
||||
|
||||
void on_result(NetQueryPtr net_query) override;
|
||||
|
||||
void init();
|
||||
|
||||
void start_up() override;
|
||||
void loop() override;
|
||||
};
|
||||
|
@ -176,7 +176,7 @@ class Status {
|
||||
|
||||
void ensure_impl(CSlice file_name, int line) const {
|
||||
if (!is_ok()) {
|
||||
LOG(FATAL) << "Unexpexted Status " << to_string() << " in file " << file_name << " at line " << line;
|
||||
LOG(FATAL) << "Unexpected Status " << to_string() << " in file " << file_name << " at line " << line;
|
||||
}
|
||||
}
|
||||
void ensure_error_impl(CSlice file_name, int line) const {
|
||||
|
Loading…
Reference in New Issue
Block a user