Save time zones to binlog.

This commit is contained in:
levlam 2024-02-19 22:30:07 +03:00
parent ab1b7cf20f
commit d5af2f6ced
2 changed files with 82 additions and 0 deletions

View File

@ -7,11 +7,13 @@
#include "td/telegram/TimeZoneManager.h" #include "td/telegram/TimeZoneManager.h"
#include "td/telegram/Global.h" #include "td/telegram/Global.h"
#include "td/telegram/logevent/LogEvent.h"
#include "td/telegram/Td.h" #include "td/telegram/Td.h"
#include "td/telegram/telegram_api.h" #include "td/telegram/telegram_api.h"
#include "td/utils/algorithm.h" #include "td/utils/algorithm.h"
#include "td/utils/buffer.h" #include "td/utils/buffer.h"
#include "td/utils/tl_helpers.h"
namespace td { namespace td {
@ -60,11 +62,42 @@ bool operator!=(const TimeZoneManager::TimeZone &lhs, const TimeZoneManager::Tim
return !(lhs == rhs); return !(lhs == rhs);
} }
template <class StorerT>
void TimeZoneManager::TimeZone::store(StorerT &storer) const {
BEGIN_STORE_FLAGS();
END_STORE_FLAGS();
td::store(id_, storer);
td::store(name_, storer);
td::store(utc_offset_, storer);
}
template <class ParserT>
void TimeZoneManager::TimeZone::parse(ParserT &parser) {
BEGIN_PARSE_FLAGS();
END_PARSE_FLAGS();
td::parse(id_, parser);
td::parse(name_, parser);
td::parse(utc_offset_, parser);
}
td_api::object_ptr<td_api::timeZones> TimeZoneManager::TimeZoneList::get_time_zones_object() const { td_api::object_ptr<td_api::timeZones> TimeZoneManager::TimeZoneList::get_time_zones_object() const {
return td_api::make_object<td_api::timeZones>( return td_api::make_object<td_api::timeZones>(
transform(time_zones_, [](const TimeZone &time_zone) { return time_zone.get_time_zone_object(); })); transform(time_zones_, [](const TimeZone &time_zone) { return time_zone.get_time_zone_object(); }));
} }
template <class StorerT>
void TimeZoneManager::TimeZoneList::store(StorerT &storer) const {
td::store(time_zones_, storer);
td::store(hash_, storer);
}
template <class ParserT>
void TimeZoneManager::TimeZoneList::parse(ParserT &parser) {
td::parse(time_zones_, parser);
td::parse(hash_, parser);
is_loaded_ = true;
}
TimeZoneManager::TimeZoneManager(Td *td, ActorShared<> parent) : td_(td), parent_(std::move(parent)) { TimeZoneManager::TimeZoneManager(Td *td, ActorShared<> parent) : td_(td), parent_(std::move(parent)) {
} }
@ -75,6 +108,7 @@ void TimeZoneManager::tear_down() {
} }
void TimeZoneManager::get_time_zones(Promise<td_api::object_ptr<td_api::timeZones>> &&promise) { void TimeZoneManager::get_time_zones(Promise<td_api::object_ptr<td_api::timeZones>> &&promise) {
load_time_zones();
if (time_zones_.hash_ != 0) { if (time_zones_.hash_ != 0) {
return promise.set_value(time_zones_.get_time_zones_object()); return promise.set_value(time_zones_.get_time_zones_object());
} }
@ -82,6 +116,7 @@ void TimeZoneManager::get_time_zones(Promise<td_api::object_ptr<td_api::timeZone
} }
void TimeZoneManager::reload_time_zones(Promise<td_api::object_ptr<td_api::timeZones>> &&promise) { void TimeZoneManager::reload_time_zones(Promise<td_api::object_ptr<td_api::timeZones>> &&promise) {
load_time_zones();
get_time_zones_queries_.push_back(std::move(promise)); get_time_zones_queries_.push_back(std::move(promise));
if (get_time_zones_queries_.size() == 1) { if (get_time_zones_queries_.size() == 1) {
auto query_promise = PromiseCreator::lambda( auto query_promise = PromiseCreator::lambda(
@ -112,12 +147,15 @@ void TimeZoneManager::on_get_time_zones(
if (time_zones_.time_zones_ != time_zones || time_zones_.hash_ != zone_list->hash_) { if (time_zones_.time_zones_ != time_zones || time_zones_.hash_ != zone_list->hash_) {
time_zones_.time_zones_ = std::move(time_zones); time_zones_.time_zones_ = std::move(time_zones);
time_zones_.hash_ = zone_list->hash_; time_zones_.hash_ = zone_list->hash_;
save_time_zones();
} }
break; break;
} }
default: default:
UNREACHABLE(); UNREACHABLE();
} }
time_zones_.is_loaded_ = true;
auto promises = std::move(get_time_zones_queries_); auto promises = std::move(get_time_zones_queries_);
reset_to_empty(get_time_zones_queries_); reset_to_empty(get_time_zones_queries_);
for (auto &promise : promises) { for (auto &promise : promises) {
@ -127,4 +165,29 @@ void TimeZoneManager::on_get_time_zones(
} }
} }
string TimeZoneManager::get_time_zones_database_key() {
return "time_zones";
}
void TimeZoneManager::load_time_zones() {
if (time_zones_.is_loaded_) {
return;
}
time_zones_.is_loaded_ = true;
auto log_event_string = G()->td_db()->get_binlog_pmc()->get(get_time_zones_database_key());
if (log_event_string.empty()) {
return;
}
auto status = log_event_parse(time_zones_, log_event_string);
if (status.is_error()) {
LOG(ERROR) << "Failed to parse time zones from binlog: " << status;
time_zones_ = TimeZoneList();
}
}
void TimeZoneManager::save_time_zones() {
G()->td_db()->get_binlog_pmc()->set(get_time_zones_database_key(), log_event_store(time_zones_).as_slice().str());
}
} // namespace td } // namespace td

View File

@ -43,13 +43,26 @@ class TimeZoneManager final : public Actor {
TimeZone(string &&id, string &&name, int32 utc_offset); TimeZone(string &&id, string &&name, int32 utc_offset);
td_api::object_ptr<td_api::timeZone> get_time_zone_object() const; td_api::object_ptr<td_api::timeZone> get_time_zone_object() const;
template <class StorerT>
void store(StorerT &storer) const;
template <class ParserT>
void parse(ParserT &parser);
}; };
struct TimeZoneList { struct TimeZoneList {
vector<TimeZone> time_zones_; vector<TimeZone> time_zones_;
int32 hash_ = 0; int32 hash_ = 0;
bool is_loaded_ = false;
td_api::object_ptr<td_api::timeZones> get_time_zones_object() const; td_api::object_ptr<td_api::timeZones> get_time_zones_object() const;
template <class StorerT>
void store(StorerT &storer) const;
template <class ParserT>
void parse(ParserT &parser);
}; };
friend bool operator==(const TimeZone &lhs, const TimeZone &rhs); friend bool operator==(const TimeZone &lhs, const TimeZone &rhs);
@ -58,6 +71,12 @@ class TimeZoneManager final : public Actor {
void on_get_time_zones(Result<telegram_api::object_ptr<telegram_api::help_TimezonesList>> &&r_time_zones); void on_get_time_zones(Result<telegram_api::object_ptr<telegram_api::help_TimezonesList>> &&r_time_zones);
static string get_time_zones_database_key();
void load_time_zones();
void save_time_zones();
vector<Promise<td_api::object_ptr<td_api::timeZones>>> get_time_zones_queries_; vector<Promise<td_api::object_ptr<td_api::timeZones>>> get_time_zones_queries_;
TimeZoneList time_zones_; TimeZoneList time_zones_;