diff --git a/td/telegram/ConfigManager.cpp b/td/telegram/ConfigManager.cpp index ea496fcef..cb6f095b3 100644 --- a/td/telegram/ConfigManager.cpp +++ b/td/telegram/ConfigManager.cpp @@ -781,6 +781,11 @@ class ConfigRecoverer final : public Actor { if (close_flag_) { return; } + if (Session::is_high_loaded()) { + VLOG(config_recoverer) << "Skip config recoverer under high load"; + set_timeout_in(Random::fast(200, 300)); + return; + } if (is_connecting_) { VLOG(config_recoverer) << "Failed to connect for " << Time::now() - connecting_since_; diff --git a/td/telegram/net/Session.cpp b/td/telegram/net/Session.cpp index c04ce0f22..ce540b5bd 100644 --- a/td/telegram/net/Session.cpp +++ b/td/telegram/net/Session.cpp @@ -44,6 +44,7 @@ #include "td/utils/utf8.h" #include "td/utils/VectorQueue.h" +#include #include #include #include @@ -109,6 +110,22 @@ class GenAuthKeyActor final : public Actor { , connection_promise_(std::move(connection_promise)) , handshake_promise_(std::move(handshake_promise)) , callback_(std::move(callback)) { + if (actor_count_.fetch_add(1, std::memory_order_relaxed) == MIN_HIGH_LOAD_ACTOR_COUNT - 1) { + LOG(WARNING) << "Number of GenAuthKeyActor exceeded high-load threshold"; + } + } + GenAuthKeyActor(const GenAuthKeyActor &) = delete; + GenAuthKeyActor &operator=(const GenAuthKeyActor &) = delete; + GenAuthKeyActor(GenAuthKeyActor &&) = delete; + GenAuthKeyActor &operator=(GenAuthKeyActor &&) = delete; + ~GenAuthKeyActor() final { + if (actor_count_.fetch_sub(1, std::memory_order_relaxed) == MIN_HIGH_LOAD_ACTOR_COUNT) { + LOG(WARNING) << "Number of GenAuthKeyActor became lower than high-load threshold"; + } + } + + static bool is_high_loaded() { + return actor_count_.load(std::memory_order_relaxed) >= MIN_HIGH_LOAD_ACTOR_COUNT; } void on_network(uint32 network_generation) { @@ -130,6 +147,9 @@ class GenAuthKeyActor final : public Actor { ActorOwn child_; Promise finish_promise_; + static constexpr size_t MIN_HIGH_LOAD_ACTOR_COUNT = 100; + static std::atomic actor_count_; + static TD_THREAD_LOCAL Semaphore *semaphore_; Semaphore &get_handshake_semaphore() { auto old_context = set_context(std::make_shared()); @@ -187,6 +207,7 @@ class GenAuthKeyActor final : public Actor { } }; +std::atomic GenAuthKeyActor::actor_count_; TD_THREAD_LOCAL Semaphore *GenAuthKeyActor::semaphore_{}; } // namespace detail @@ -258,6 +279,10 @@ Session::Session(unique_ptr callback, std::shared_ptr last_bind_success_timestamp_ = Time::now() - 366 * 86400; } +bool Session::is_high_loaded() { + return detail::GenAuthKeyActor::is_high_loaded(); +} + bool Session::can_destroy_auth_key() const { return need_destroy_; } diff --git a/td/telegram/net/Session.h b/td/telegram/net/Session.h index d46779195..cd4aae77a 100644 --- a/td/telegram/net/Session.h +++ b/td/telegram/net/Session.h @@ -74,6 +74,8 @@ class Session final void close(); + static bool is_high_loaded(); + private: struct Query final : private ListNode { uint64 container_id;