Files
qt6-migration-pipeline/TetraIF/PrtCnv/PrtCnvRadioTrafficThread.cpp
T
2026-07-14 12:07:36 +02:00

209 lines
6.1 KiB
C++

#include "PrtCnvRadioTrafficThread.hpp"
#include "PrtCnvDbThread.hpp"
#include "PrtCnvThreadStarter.hpp"
#include <QtCore/QTimer>
#include <CoPrtCnv/CoPrtCnvRadioTelegram.hpp>
#include <CoPrtCnv/CoPrtCnvTelegramConverter.hpp>
#include <time.h>
namespace PrtCnv
{
PrtCnvRadioTrafficThread::PrtCnvRadioTrafficThread(PrtCnvThreadStarter* a_parent)
: PrtCnvThread(a_parent, "PrtCnvRadioTrafficThread")
, m_receiveLoad(PrtCnvRadioThread::E_TrafficLoad::Unknown)
, m_fullLoad(100)
, m_highLoad(50)
, m_hystLoad(5)
, m_calcTimeout(1000)
, m_cleanupTimeout(5000)
, m_mutex(QMutex::Recursive)
{}
void PrtCnvRadioTrafficThread::newTelegramArrived(unsigned int size)
{
time_t curTime = time(nullptr);
QMutexLocker l(&m_mutex);
DEBUG_LOG(m_logger) << "newTelegramArrived with size " << size << " at " << curTime;
m_data[curTime] += size;
m_telegrams[curTime]++;
}
int32_t PrtCnvRadioTrafficThread::start()
{
const QString trafficControlGroup(QStringLiteral("TrafficControl"));
int highLoad = m_Config->getInteger(trafficControlGroup, QStringLiteral("ReceiveQueueHighLoad"), 60);
int fullLoad = m_Config->getInteger(trafficControlGroup, QStringLiteral("ReceiveQueueFullLoad"), 80);
int hystLoad = m_Config->getInteger(trafficControlGroup, QStringLiteral("ReceiveQueueHysteresis"), 5);
int avgTime = m_Config->getInteger(trafficControlGroup, QStringLiteral("ReceiveAveragingTime"), 5);
float trafficPerReceiverKB = m_Config->getFloat(trafficControlGroup, QStringLiteral("ReceiveThroughput"), 3.6f);
int cntTransceiver = m_Config->getInteger(trafficControlGroup, QStringLiteral("TransceiverCount"), 6);
if (highLoad < 0 || highLoad > 100)
highLoad = 60;
if (fullLoad < highLoad || fullLoad > 100)
fullLoad = 80;
if (hystLoad < 0 || hystLoad > 10)
hystLoad = 5;
if (avgTime <= 0 || avgTime > 60)
avgTime = 5;
if (trafficPerReceiverKB < 1 || trafficPerReceiverKB > 1000)
trafficPerReceiverKB = 3.6f;
if (cntTransceiver < 1 || cntTransceiver > 100)
cntTransceiver = 6;
float maxTrafficBytes = trafficPerReceiverKB * cntTransceiver * 1024;
m_fullLoad = maxTrafficBytes * fullLoad / 100.f;
m_highLoad = maxTrafficBytes * highLoad / 100.f;
m_hystLoad = maxTrafficBytes * hystLoad / 100.f;
m_cleanupTimeout = avgTime * 1000;
DEBUG_LOG(m_logger) << "Read config ReceiveQueueHighLoad: " << highLoad;
DEBUG_LOG(m_logger) << "Read config ReceiveQueueFullLoad: " << fullLoad;
DEBUG_LOG(m_logger) << "Read config ReceiveQueueHysteresis: " << hystLoad;
DEBUG_LOG(m_logger) << "Read config ReceiveAveragingTime: " << avgTime;
DEBUG_LOG(m_logger) << "Read config ReceiveThroughput: " << trafficPerReceiverKB;
DEBUG_LOG(m_logger) << "Read config TransceiverCount: " << cntTransceiver;
INFO_LOG(m_logger) << "Using to following limits: high - " << m_highLoad
<< " full - " << m_fullLoad
<< " hyst - " << m_hystLoad
<< " avg. time - " << m_cleanupTimeout / 1000;
QTimer::singleShot(m_calcTimeout, this, &PrtCnvRadioTrafficThread::onCalculateTrafficLoad);
QTimer::singleShot(m_cleanupTimeout, this, &PrtCnvRadioTrafficThread::onCleanupTimeout);
return 0;
}
void PrtCnvRadioTrafficThread::onCalculateTrafficLoad()
{
const time_t curTime = time(nullptr);
unsigned int payload = 0;
{
QMutexLocker l(&m_mutex);
for (int i = 1; i <= m_cleanupTimeout / 1000; ++i)
payload += m_data.value(curTime - i);
}
payload /= (m_cleanupTimeout / 1000);
INFO_LOG(m_logger) << "Average Payload in the last "
<< m_cleanupTimeout << " Milliseconds: "
<< payload << " Bytes/sec, last sec: "
<< m_data[curTime - 1] << " Bytes, #telegrams: " << m_telegrams[curTime - 1];
PrtCnvRadioThread::E_TrafficLoad newReceiveLoad;
if (payload >= m_fullLoad)
{
newReceiveLoad = PrtCnvRadioThread::E_TrafficLoad::FullLoad;
if (m_receiveLoad == PrtCnvRadioThread::E_TrafficLoad::HighLoad)
{
if(payload < m_fullLoad + m_hystLoad)
newReceiveLoad = PrtCnvRadioThread::E_TrafficLoad::HighLoad;
}
}
else if (payload >= m_highLoad)
{
newReceiveLoad = PrtCnvRadioThread::E_TrafficLoad::HighLoad;
if (m_receiveLoad == PrtCnvRadioThread::E_TrafficLoad::NormalLoad)
{
if (payload < m_highLoad + m_hystLoad)
newReceiveLoad = PrtCnvRadioThread::E_TrafficLoad::NormalLoad;
}
if (m_receiveLoad == PrtCnvRadioThread::E_TrafficLoad::FullLoad)
{
if (payload >= m_fullLoad - m_hystLoad)
newReceiveLoad = PrtCnvRadioThread::E_TrafficLoad::FullLoad;
}
}
else
{
newReceiveLoad = PrtCnvRadioThread::E_TrafficLoad::NormalLoad;
if (m_receiveLoad == PrtCnvRadioThread::E_TrafficLoad::HighLoad)
{
if(payload >= m_highLoad - m_hystLoad)
newReceiveLoad = PrtCnvRadioThread::E_TrafficLoad::HighLoad;
}
}
if (m_receiveLoad != newReceiveLoad)
{
m_receiveLoad = newReceiveLoad;
unsigned int wartezeit_posmldg = (static_cast<unsigned int>(m_receiveLoad) * 10) + 1;
INFO_LOG(m_logger) << "New traffic load: " << m_receiveLoad;
PrtCnvDbThread *dbThread = qobject_cast<PrtCnvDbThread*>(m_Parent->getOtherThread(PrtCnvApplication::e_Db));
if (dbThread)
{
dbThread->setAirLoad(m_receiveLoad);
dbThread->setPositionSendTime(wartezeit_posmldg);
Q_ASSERT(QThread::currentThreadId() == m_currentThreadId);
}
else
ERROR_LOG(m_logger) << "Could not get PrtCnvDbThread!";
}
QTimer::singleShot(m_calcTimeout, this, &PrtCnvRadioTrafficThread::onCalculateTrafficLoad);
}
void PrtCnvRadioTrafficThread::onCleanupTimeout()
{
const time_t curTime = time(nullptr);
{
QMutexLocker l(&m_mutex);
QMap<time_t, unsigned int>::iterator it = m_data.begin();
while (it != m_data.end())
{
const time_t key = it.key();
if (key < curTime - m_cleanupTimeout - 10)
{
m_data.erase(it++);
m_telegrams.remove(key);
continue;
}
break;
}
}
QTimer::singleShot(m_cleanupTimeout, this, &PrtCnvRadioTrafficThread::onCleanupTimeout);
}
}