diff --git a/Telegram/CMakeLists.txt b/Telegram/CMakeLists.txt index 39dc186cc..b8fbab91a 100644 --- a/Telegram/CMakeLists.txt +++ b/Telegram/CMakeLists.txt @@ -164,6 +164,8 @@ PRIVATE api/api_single_message_search.h api/api_statistics.cpp api/api_statistics.h + api/api_statistics_sender.cpp + api/api_statistics_sender.h api/api_text_entities.cpp api/api_text_entities.h api/api_toggling_media.cpp diff --git a/Telegram/SourceFiles/api/api_statistics.cpp b/Telegram/SourceFiles/api/api_statistics.cpp index 70c2a6ae7..a017571a9 100644 --- a/Telegram/SourceFiles/api/api_statistics.cpp +++ b/Telegram/SourceFiles/api/api_statistics.cpp @@ -20,8 +20,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL namespace Api { namespace { -constexpr auto kCheckRequestsTimer = 10 * crl::time(1000); - [[nodiscard]] Data::StatisticalGraph StatisticalGraphFromTL( const MTPStatsGraph &tl) { return tl.match([&](const MTPDstatsGraph &d) { @@ -223,61 +221,6 @@ Statistics::Statistics(not_null channel) : StatisticsRequestSender(channel) { } -StatisticsRequestSender::StatisticsRequestSender(not_null channel) -: _channel(channel) -, _api(&_channel->session().api().instance()) -, _timer([=] { checkRequests(); }) { -} - -StatisticsRequestSender::~StatisticsRequestSender() { - for (const auto &[dcId, ids] : _requests) { - for (const auto id : ids) { - _channel->session().api().unregisterStatsRequest(dcId, id); - } - } -} - -void StatisticsRequestSender::checkRequests() { - for (auto i = begin(_requests); i != end(_requests);) { - for (auto j = begin(i->second); j != end(i->second);) { - if (_api.pending(*j)) { - ++j; - } else { - _channel->session().api().unregisterStatsRequest( - i->first, - *j); - j = i->second.erase(j); - } - } - if (i->second.empty()) { - i = _requests.erase(i); - } else { - ++i; - } - } - if (_requests.empty()) { - _timer.cancel(); - } -} - -template -auto StatisticsRequestSender::makeRequest(Request &&request) { - const auto id = _api.allocateRequestId(); - const auto dcId = _channel->owner().statsDcId(_channel); - if (dcId) { - _channel->session().api().registerStatsRequest(dcId, id); - _requests[dcId].emplace(id); - if (!_timer.isActive()) { - _timer.callEach(kCheckRequestsTimer); - } - } - return std::move(_api.request( - std::forward(request) - ).toDC( - dcId ? MTP::ShiftDcId(dcId, MTP::kStatsDcShift) : 0 - ).overrideId(id)); -} - rpl::producer Statistics::request() { return [=](auto consumer) { auto lifetime = rpl::lifetime(); diff --git a/Telegram/SourceFiles/api/api_statistics.h b/Telegram/SourceFiles/api/api_statistics.h index eca157ff0..213ab9293 100644 --- a/Telegram/SourceFiles/api/api_statistics.h +++ b/Telegram/SourceFiles/api/api_statistics.h @@ -7,45 +7,16 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #pragma once -#include "base/timer.h" +#include "api/api_statistics_sender.h" #include "data/data_boosts.h" #include "data/data_channel_earn.h" #include "data/data_statistics.h" -#include "mtproto/sender.h" class ChannelData; class PeerData; namespace Api { -class StatisticsRequestSender { -protected: - explicit StatisticsRequestSender(not_null channel); - ~StatisticsRequestSender(); - - template < - typename Request, - typename = std::enable_if_t>, - typename = typename Request::Unboxed> - [[nodiscard]] auto makeRequest(Request &&request); - - [[nodiscard]] MTP::Sender &api() { - return _api; - } - [[nodiscard]] not_null channel() { - return _channel; - } - -private: - void checkRequests(); - - const not_null _channel; - MTP::Sender _api; - base::Timer _timer; - base::flat_map> _requests; - -}; - class Statistics final : public StatisticsRequestSender { public: explicit Statistics(not_null channel); diff --git a/Telegram/SourceFiles/api/api_statistics_sender.cpp b/Telegram/SourceFiles/api/api_statistics_sender.cpp new file mode 100644 index 000000000..21d068e3d --- /dev/null +++ b/Telegram/SourceFiles/api/api_statistics_sender.cpp @@ -0,0 +1,86 @@ +/* +This file is part of Telegram Desktop, +the official desktop application for the Telegram messaging service. + +For license and copyright information please follow this link: +https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL +*/ +#include "api/api_statistics_sender.h" + +#include "apiwrap.h" +#include "data/data_peer.h" +#include "data/data_session.h" +#include "main/main_session.h" + +namespace Api { + +StatisticsRequestSender::StatisticsRequestSender( + not_null peer) +: _peer(peer) +, _channel(peer->asChannel()) +, _user(peer->asUser()) +, _api(&_peer->session().api().instance()) +, _timer([=] { checkRequests(); }) { +} + +MTP::Sender &StatisticsRequestSender::api() { + return _api; +} + +not_null StatisticsRequestSender::channel() { + Expects(_channel); + return _channel; +} + +not_null StatisticsRequestSender::user() { + Expects(_user); + return _user; +} + +void StatisticsRequestSender::checkRequests() { + for (auto i = begin(_requests); i != end(_requests);) { + for (auto j = begin(i->second); j != end(i->second);) { + if (_api.pending(*j)) { + ++j; + } else { + _peer->session().api().unregisterStatsRequest( + i->first, + *j); + j = i->second.erase(j); + } + } + if (i->second.empty()) { + i = _requests.erase(i); + } else { + ++i; + } + } + if (_requests.empty()) { + _timer.cancel(); + } +} + +auto StatisticsRequestSender::ensureRequestIsRegistered() +-> StatisticsRequestSender::Registered { + const auto id = _api.allocateRequestId(); + const auto dcId = _peer->owner().statsDcId(_peer); + if (dcId) { + _peer->session().api().registerStatsRequest(dcId, id); + _requests[dcId].emplace(id); + if (!_timer.isActive()) { + constexpr auto kCheckRequestsTimer = 10 * crl::time(1000); + _timer.callEach(kCheckRequestsTimer); + } + } + return StatisticsRequestSender::Registered{ id, dcId }; +} + +StatisticsRequestSender::~StatisticsRequestSender() { + for (const auto &[dcId, ids] : _requests) { + for (const auto id : ids) { + _peer->session().api().unregisterStatsRequest(dcId, id); + } + } +} + +} // namespace Api diff --git a/Telegram/SourceFiles/api/api_statistics_sender.h b/Telegram/SourceFiles/api/api_statistics_sender.h new file mode 100644 index 000000000..2ad0b664d --- /dev/null +++ b/Telegram/SourceFiles/api/api_statistics_sender.h @@ -0,0 +1,58 @@ +/* +This file is part of Telegram Desktop, +the official desktop application for the Telegram messaging service. + +For license and copyright information please follow this link: +https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL +*/ +#pragma once + +#include "base/timer.h" +#include "mtproto/sender.h" + +class ChannelData; +class PeerData; +class UserData; + +namespace Api { + +class StatisticsRequestSender { +protected: + explicit StatisticsRequestSender(not_null peer); + ~StatisticsRequestSender(); + + template < + typename Request, + typename = std::enable_if_t>, + typename = typename Request::Unboxed> + [[nodiscard]] auto makeRequest(Request &&request) { + const auto [id, dcId] = ensureRequestIsRegistered(); + return std::move(_api.request( + std::forward(request) + ).toDC( + dcId ? MTP::ShiftDcId(dcId, MTP::kStatsDcShift) : 0 + ).overrideId(id)); + } + + [[nodiscard]] MTP::Sender &api(); + [[nodiscard]] not_null channel(); + [[nodiscard]] not_null user(); + +private: + struct Registered final { + mtpRequestId id; + MTP::DcId dcId; + }; + [[nodiscard]] Registered ensureRequestIsRegistered(); + void checkRequests(); + + const not_null _peer; + ChannelData * const _channel; + UserData * const _user; + MTP::Sender _api; + base::Timer _timer; + base::flat_map> _requests; + +}; + +} // namespace Api diff --git a/Telegram/SourceFiles/data/data_session.cpp b/Telegram/SourceFiles/data/data_session.cpp index c11c2ef8a..b22126ebb 100644 --- a/Telegram/SourceFiles/data/data_session.cpp +++ b/Telegram/SourceFiles/data/data_session.cpp @@ -4683,16 +4683,16 @@ uint64 Session::wallpapersHash() const { return _wallpapersHash; } -MTP::DcId Session::statsDcId(not_null channel) { - const auto it = _channelStatsDcIds.find(channel); - return (it == end(_channelStatsDcIds)) ? MTP::DcId(0) : it->second; +MTP::DcId Session::statsDcId(not_null peer) { + const auto it = _peerStatsDcIds.find(peer); + return (it == end(_peerStatsDcIds)) ? MTP::DcId(0) : it->second; } void Session::applyStatsDcId( - not_null channel, + not_null peer, MTP::DcId dcId) { - if (dcId != channel->session().mainDcId()) { - _channelStatsDcIds[channel] = dcId; + if (dcId != peer->session().mainDcId()) { + _peerStatsDcIds[peer] = dcId; } } diff --git a/Telegram/SourceFiles/data/data_session.h b/Telegram/SourceFiles/data/data_session.h index 117823802..12c4cba3a 100644 --- a/Telegram/SourceFiles/data/data_session.h +++ b/Telegram/SourceFiles/data/data_session.h @@ -753,8 +753,8 @@ public: [[nodiscard]] auto peerDecorationsUpdated() const -> rpl::producer>; - void applyStatsDcId(not_null, MTP::DcId); - [[nodiscard]] MTP::DcId statsDcId(not_null); + void applyStatsDcId(not_null, MTP::DcId); + [[nodiscard]] MTP::DcId statsDcId(not_null); void viewTagsChanged( not_null view, @@ -1053,7 +1053,7 @@ private: base::flat_map, TimeId> _watchingForOffline; base::Timer _watchForOfflineTimer; - base::flat_map, MTP::DcId> _channelStatsDcIds; + base::flat_map, MTP::DcId> _peerStatsDcIds; rpl::event_stream _webViewResultSent;