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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
//
|
//
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "td/mtproto/utils.h"
|
#include "td/mtproto/utils.h"
|
||||||
|
|
||||||
#include "td/utils/common.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,
|
static void write_crypto_impl(int X, const Storer &storer, const AuthKey &auth_key, PacketInfo *info, HeaderT *header,
|
||||||
size_t data_size);
|
size_t data_size);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace mtproto
|
} // namespace mtproto
|
||||||
} // namespace td
|
} // namespace td
|
||||||
|
@ -4262,9 +4262,13 @@ void Td::on_config_option_updated(const string &name) {
|
|||||||
send_closure(storage_manager_, &StorageManager::update_use_storage_optimizer);
|
send_closure(storage_manager_, &StorageManager::update_use_storage_optimizer);
|
||||||
} else if (name == "rating_e_decay") {
|
} else if (name == "rating_e_decay") {
|
||||||
return send_closure(top_dialog_manager_, &TopDialogManager::update_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)) {
|
} else if (is_internal_config_option(name)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// send_closure was already used in the callback
|
// send_closure was already used in the callback
|
||||||
send_update(make_tl_object<td_api::updateOption>(name, G()->shared_config().get_option_value(name)));
|
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")) {
|
if (set_boolean_option("disable_contact_registered_notifications")) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (set_boolean_option("disable_top_chats")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 'i':
|
case 'i':
|
||||||
if (set_boolean_option("ignore_inline_thumbnails")) {
|
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) {
|
void TopDialogManager::on_dialog_used(TopDialogCategory category, DialogId dialog_id, int32 date) {
|
||||||
if (!is_active_) {
|
if (!is_active_ || !is_enabled_) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto pos = static_cast<size_t>(category);
|
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,
|
void TopDialogManager::remove_dialog(TopDialogCategory category, DialogId dialog_id,
|
||||||
tl_object_ptr<telegram_api::InputPeer> input_peer) {
|
tl_object_ptr<telegram_api::InputPeer> input_peer) {
|
||||||
if (!is_active_) {
|
if (!is_active_ || !is_enabled_) {
|
||||||
return;
|
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"));
|
promise.set_error(Status::Error(400, "Not supported without chat info database"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (!is_enabled_) {
|
||||||
|
promise.set_error(Status::Error(400, "Top chats computation is disabled"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
GetTopDialogsQuery query;
|
GetTopDialogsQuery query;
|
||||||
query.category = category;
|
query.category = category;
|
||||||
query.limit = limit;
|
query.limit = limit;
|
||||||
@ -302,33 +341,66 @@ void TopDialogManager::do_get_top_peers() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void TopDialogManager::on_result(NetQueryPtr net_query) {
|
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;
|
return;
|
||||||
}
|
}
|
||||||
SCOPE_EXIT {
|
SCOPE_EXIT {
|
||||||
loop();
|
loop();
|
||||||
};
|
};
|
||||||
|
|
||||||
normalize_rating(); // once a day too
|
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));
|
auto r_top_peers = fetch_result<telegram_api::contacts_getTopPeers>(std::move(net_query));
|
||||||
if (r_top_peers.is_error()) {
|
if (r_top_peers.is_error()) {
|
||||||
LOG(ERROR) << "contacts_getTopPeers failed: " << r_top_peers.error();
|
last_server_sync_ = Timestamp::in(SERVER_SYNC_RESEND_DELAY - SERVER_SYNC_DELAY);
|
||||||
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
|
|
||||||
return;
|
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));
|
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_));
|
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;
|
db_sync_state_ = SyncState::None;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
UNREACHABLE();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TopDialogManager::do_save_top_dialogs() {
|
void TopDialogManager::do_save_top_dialogs() {
|
||||||
@ -370,12 +447,31 @@ void TopDialogManager::do_save_top_dialogs() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void TopDialogManager::start_up() {
|
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");
|
G()->td_db()->get_binlog_pmc()->erase_by_prefix("top_dialogs");
|
||||||
is_active_ = false;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
is_active_ = true;
|
|
||||||
|
|
||||||
auto di_top_dialogs_ts = G()->td_db()->get_binlog_pmc()->get("top_dialogs_ts");
|
auto di_top_dialogs_ts = G()->td_db()->get_binlog_pmc()->get("top_dialogs_ts");
|
||||||
if (!di_top_dialogs_ts.empty()) {
|
if (!di_top_dialogs_ts.empty()) {
|
||||||
@ -384,8 +480,8 @@ void TopDialogManager::start_up() {
|
|||||||
server_sync_state_ = SyncState::Ok;
|
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++) {
|
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 top_dialog_category = TopDialogCategory(top_dialog_category_i);
|
||||||
auto key = PSTRING() << "top_dialogs#" << top_dialog_category_name(top_dialog_category);
|
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();
|
log_event_parse(top_dialogs, value).ensure();
|
||||||
}
|
}
|
||||||
normalize_rating();
|
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;
|
db_sync_state_ = SyncState::Ok;
|
||||||
|
|
||||||
send_closure(G()->state_manager(), &StateManager::wait_first_sync,
|
send_closure(G()->state_manager(), &StateManager::wait_first_sync,
|
||||||
PromiseCreator::event(self_closure(this, &TopDialogManager::on_first_sync)));
|
PromiseCreator::event(self_closure(this, &TopDialogManager::on_first_sync)));
|
||||||
|
|
||||||
loop();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TopDialogManager::on_first_sync() {
|
void TopDialogManager::on_first_sync() {
|
||||||
@ -441,6 +543,7 @@ void TopDialogManager::loop() {
|
|||||||
do_get_top_peers();
|
do_get_top_peers();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (is_enabled_) {
|
||||||
// db sync
|
// db sync
|
||||||
Timestamp db_sync_timeout;
|
Timestamp db_sync_timeout;
|
||||||
if (db_sync_state_ == SyncState::Ok) {
|
if (db_sync_state_ == SyncState::Ok) {
|
||||||
@ -459,6 +562,7 @@ void TopDialogManager::loop() {
|
|||||||
do_save_top_dialogs();
|
do_save_top_dialogs();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (wakeup_timeout) {
|
if (wakeup_timeout) {
|
||||||
LOG(INFO) << "Wakeup in: " << wakeup_timeout.in();
|
LOG(INFO) << "Wakeup in: " << wakeup_timeout.in();
|
||||||
|
@ -57,13 +57,23 @@ class TopDialogManager : public NetQueryCallback {
|
|||||||
|
|
||||||
void update_rating_e_decay();
|
void update_rating_e_decay();
|
||||||
|
|
||||||
|
void update_is_enabled(bool is_enabled);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static constexpr size_t MAX_TOP_DIALOGS_LIMIT = 30;
|
static constexpr size_t MAX_TOP_DIALOGS_LIMIT = 30;
|
||||||
static constexpr int32 SERVER_SYNC_DELAY = 86400; // seconds
|
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
|
static constexpr int32 DB_SYNC_DELAY = 5; // seconds
|
||||||
ActorShared<> parent_;
|
ActorShared<> parent_;
|
||||||
|
|
||||||
bool is_active_{false};
|
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};
|
bool was_first_sync_{false};
|
||||||
enum class SyncState : int32 { None, Pending, Ok };
|
enum class SyncState : int32 { None, Pending, Ok };
|
||||||
SyncState db_sync_state_ = SyncState::None;
|
SyncState db_sync_state_ = SyncState::None;
|
||||||
@ -106,7 +116,8 @@ class TopDialogManager : public NetQueryCallback {
|
|||||||
double current_rating_add(double rating_timestamp) const;
|
double current_rating_add(double rating_timestamp) const;
|
||||||
void normalize_rating();
|
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);
|
void do_get_top_dialogs(GetTopDialogsQuery &&query);
|
||||||
|
|
||||||
@ -117,6 +128,8 @@ class TopDialogManager : public NetQueryCallback {
|
|||||||
|
|
||||||
void on_result(NetQueryPtr net_query) override;
|
void on_result(NetQueryPtr net_query) override;
|
||||||
|
|
||||||
|
void init();
|
||||||
|
|
||||||
void start_up() override;
|
void start_up() override;
|
||||||
void loop() override;
|
void loop() override;
|
||||||
};
|
};
|
||||||
|
@ -176,7 +176,7 @@ class Status {
|
|||||||
|
|
||||||
void ensure_impl(CSlice file_name, int line) const {
|
void ensure_impl(CSlice file_name, int line) const {
|
||||||
if (!is_ok()) {
|
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 {
|
void ensure_error_impl(CSlice file_name, int line) const {
|
||||||
|
Loading…
Reference in New Issue
Block a user