[traffic] Do not announce traffic updates if nothing has changed

Signed-off-by: mvglasow <michael -at- vonglasow.com>
This commit is contained in:
mvglasow
2025-07-06 20:49:55 +03:00
parent 6656c7e441
commit 121bdc4af8
2 changed files with 22 additions and 4 deletions

View File

@@ -558,19 +558,24 @@ void TrafficManager::PurgeExpiredMessages()
OnTrafficDataUpdate(); OnTrafficDataUpdate();
} }
void TrafficManager::PurgeExpiredMessagesImpl() bool TrafficManager::PurgeExpiredMessagesImpl()
{ {
std::lock_guard<std::mutex> lock(m_mutex); std::lock_guard<std::mutex> lock(m_mutex);
bool result = false;
LOG(LINFO, ("before:", m_messageCache.size(), "message(s)")); LOG(LINFO, ("before:", m_messageCache.size(), "message(s)"));
traffxml::IsoTime now = traffxml::IsoTime::Now(); traffxml::IsoTime now = traffxml::IsoTime::Now();
for (auto it = m_messageCache.begin(); it != m_messageCache.end(); ) for (auto it = m_messageCache.begin(); it != m_messageCache.end(); )
{ {
if (it->second.IsExpired(now)) if (it->second.IsExpired(now))
{
it = m_messageCache.erase(it); it = m_messageCache.erase(it);
result = true;
}
else else
++it; ++it;
} }
LOG(LINFO, ("after:", m_messageCache.size(), "message(s)")); LOG(LINFO, ("after:", m_messageCache.size(), "message(s)"));
return result;
} }
void TrafficManager::ConsolidateFeedQueue() void TrafficManager::ConsolidateFeedQueue()
@@ -692,12 +697,21 @@ void TrafficManager::ThreadRoutine()
if (!IsEnabled()) if (!IsEnabled())
continue; continue;
/*
* Whether to call OnTrafficDataUpdate() at the end of the current round.
* The logic may fail to catch cases in which the first message in queue replaces another
* message without changing coloring. This would usually occur in a larger feed, where other
* messages would likely require an announcement, making this a minor issue. A single round
* (after a timeout) with no messages expired and an empty queue would not trigger an update.
*/
bool hasUpdates = false;
if (!IsTestMode()) if (!IsTestMode())
{ {
if (steady_clock::now() - lastPurged >= kPurgeInterval) if (steady_clock::now() - lastPurged >= kPurgeInterval)
{ {
lastPurged == steady_clock::now(); lastPurged == steady_clock::now();
PurgeExpiredMessagesImpl(); hasUpdates |= PurgeExpiredMessagesImpl();
} }
LOG(LINFO, ("active MWMs changed:", m_activeMwmsChanged, ", poll needed:", m_isPollNeeded)); LOG(LINFO, ("active MWMs changed:", m_activeMwmsChanged, ", poll needed:", m_isPollNeeded));
@@ -720,6 +734,7 @@ void TrafficManager::ThreadRoutine()
// consolidate feed queue (remove older messages in favor of newer ones) // consolidate feed queue (remove older messages in favor of newer ones)
ConsolidateFeedQueue(); ConsolidateFeedQueue();
hasUpdates |= !m_feedQueue.empty();
// decode one message and add it to the cache // decode one message and add it to the cache
DecodeFirstMessage(); DecodeFirstMessage();
@@ -727,7 +742,8 @@ void TrafficManager::ThreadRoutine()
// set new coloring for MWMs // set new coloring for MWMs
// `m_mutex` is obtained inside the method, no need to do it here // `m_mutex` is obtained inside the method, no need to do it here
// TODO drop the argument, use class member inside method // TODO drop the argument, use class member inside method
OnTrafficDataUpdate(); if (hasUpdates)
OnTrafficDataUpdate();
// TODO no longer needed // TODO no longer needed
#ifdef traffic_dead_code #ifdef traffic_dead_code

View File

@@ -399,8 +399,10 @@ private:
* This is the internal conterpart of `PurgeExpiredMessages()`. It is safe to call from any * This is the internal conterpart of `PurgeExpiredMessages()`. It is safe to call from any
* thread. Unlike `PurgeExpiredMessages()`, it does not wake the worker thread, making it suitable * thread. Unlike `PurgeExpiredMessages()`, it does not wake the worker thread, making it suitable
* for use on the worker thread. * for use on the worker thread.
*
* @return true if messages were purged, false if not
*/ */
void PurgeExpiredMessagesImpl(); bool PurgeExpiredMessagesImpl();
/** /**
* @brief Consolidates the feed queue. * @brief Consolidates the feed queue.