diff --git a/Telegram/SourceFiles/data/data_scheduled_messages.cpp b/Telegram/SourceFiles/data/data_scheduled_messages.cpp index 6800c2a3c..89e7a03d3 100644 --- a/Telegram/SourceFiles/data/data_scheduled_messages.cpp +++ b/Telegram/SourceFiles/data/data_scheduled_messages.cpp @@ -18,6 +18,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL namespace Data { namespace { +constexpr auto kRequestTimeLimit = 60 * crl::time(1000); + +[[nodiscard]] bool TooEarlyForRequest(crl::time received) { + return (received > 0) && (received + kRequestTimeLimit > crl::now()); +} + MTPMessage PrepareMessage(const MTPMessage &message, MsgId id) { return message.match([&](const MTPDmessageEmpty &) { return MTP_messageEmpty(MTP_int(id)); @@ -62,7 +68,8 @@ MTPMessage PrepareMessage(const MTPMessage &message, MsgId id) { } // namespace ScheduledMessages::ScheduledMessages(not_null owner) -: _session(&owner->session()) { +: _session(&owner->session()) +, _clearTimer([=] { clearOldRequests(); }) { owner->itemRemoved( ) | rpl::filter([](not_null item) { return item->isScheduled(); @@ -77,6 +84,21 @@ ScheduledMessages::~ScheduledMessages() { } } +void ScheduledMessages::clearOldRequests() { + const auto now = crl::now(); + while (true) { + const auto i = ranges::find_if(_requests, [&](const auto &value) { + const auto &request = value.second; + return !request.requestId + && (request.lastReceived + kRequestTimeLimit <= now); + }); + if (i == end(_requests)) { + break; + } + _requests.erase(i); + } +} + MsgId ScheduledMessages::lookupId(not_null item) const { Expects(item->isScheduled()); @@ -215,7 +237,7 @@ Data::MessagesSlice ScheduledMessages::list(not_null history) { void ScheduledMessages::request(not_null history) { auto &request = _requests[history]; - if (request.requestId) { + if (request.requestId || TooEarlyForRequest(request.lastReceived)) { return; } const auto i = _data.find(history); @@ -235,7 +257,11 @@ void ScheduledMessages::parse( not_null history, const MTPmessages_Messages &list) { auto &request = _requests[history]; + request.lastReceived = crl::now(); request.requestId = 0; + if (!_clearTimer.isActive()) { + _clearTimer.callOnce(kRequestTimeLimit * 2); + } list.match([&](const MTPDmessages_messagesNotModified &data) { }, [&](const auto &data) { @@ -263,9 +289,6 @@ void ScheduledMessages::parse( } updated(history, received, clear); }); - if (!request.requestId) { - _requests.remove(history); - } } HistoryItem *ScheduledMessages::append( diff --git a/Telegram/SourceFiles/data/data_scheduled_messages.h b/Telegram/SourceFiles/data/data_scheduled_messages.h index 9ae0de149..3deff1f08 100644 --- a/Telegram/SourceFiles/data/data_scheduled_messages.h +++ b/Telegram/SourceFiles/data/data_scheduled_messages.h @@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #pragma once #include "history/history_item.h" +#include "base/timer.h" class History; @@ -51,6 +52,7 @@ private: }; struct Request { mtpRequestId requestId = 0; + crl::time lastReceived = 0; }; void request(not_null history); @@ -69,9 +71,11 @@ private: void sort(List &list); void remove(not_null item); [[nodiscard]] int32 countListHash(const List &list) const; + void clearOldRequests(); const not_null _session; + base::Timer _clearTimer; base::flat_map, List> _data; base::flat_map, Request> _requests; rpl::event_stream> _updates;