Merge pull request #1880 from jolavillette/threadTick

clean rewrite of RsServer::threadTick
This commit is contained in:
csoler 2020-05-03 13:28:43 +02:00 committed by GitHub
commit 48960d548d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 145 additions and 159 deletions

View file

@ -41,11 +41,12 @@
#include "services/rseventsservice.h" #include "services/rseventsservice.h"
/**** /*******************
#define DEBUG_TICK 1 #define TICK_DEBUG 1
****/ *******************/
#define WARN_BIG_CYCLE_TIME (0.2) #define WARN_BIG_CYCLE_TIME (0.2)
#ifdef WINDOWS_SYS #ifdef WINDOWS_SYS
#include "util/rstime.h" #include "util/rstime.h"
#include <sys/timeb.h> #include <sys/timeb.h>
@ -73,9 +74,8 @@ static double getCurrentTS()
// In some cases (VOIP) it's likely that we will need to set them temporarily to a very low // In some cases (VOIP) it's likely that we will need to set them temporarily to a very low
// value, in order to favor a fast feedback // value, in order to favor a fast feedback
const double RsServer::minTimeDelta = 0.05; // 25; const double RsServer::minTickInterval = 0.05;
const double RsServer::maxTimeDelta = 0.2; const double RsServer::maxTickInterval = 0.2;
const double RsServer::kickLimit = 0.15;
RsServer::RsServer() : RsServer::RsServer() :
@ -110,19 +110,18 @@ RsServer::RsServer() :
mStatusSrv = NULL; mStatusSrv = NULL;
mGxsTunnels = NULL; mGxsTunnels = NULL;
mMin = 0;
mLoop = 0;
mLastts = getCurrentTS(); mLastts = getCurrentTS();
mLastSec = 0; /* for the slower ticked stuff */ mTickInterval = maxTickInterval ;
mTimeDelta = 0.25 ; mAvgRunDuration = 0;
mLastRunDuration = 0;
mAvgTickRate = mTimeDelta; mCycle1 = 0;
mCycle2 = 0;
mCycle3 = 0;
mCycle4 = 0;
/* caches (that need ticking) */ /* caches (that need ticking) */
/* Config */ /* config */
mConfigMgr = NULL; mConfigMgr = NULL;
mGeneralConfig = NULL; mGeneralConfig = NULL;
} }
@ -132,143 +131,132 @@ RsServer::~RsServer()
delete mGxsTrans; delete mGxsTrans;
} }
/* General Internal Helper Functions // General Internal Helper Functions ----> MUST BE LOCKED!
----> MUST BE LOCKED!
*/
/* Thread Fn: Run the Core */
void RsServer::threadTick() void RsServer::threadTick()
{ {
rstime::rs_usleep(mTimeDelta * 1000000); #ifdef TICK_DEBUG
RsDbg() << "TICK_DEBUG ticking interval "<< mTickInterval << std::endl;
#endif
// we try to tick at a regular interval which depends on the load
// if there is time left, we sleep
double timeToSleep = mTickInterval - mAvgRunDuration;
if (timeToSleep > 0)
{
#ifdef TICK_DEBUG
RsDbg() << "TICK_DEBUG will sleep " << timeToSleep << " ms" << std::endl;
#endif
rstime::rs_usleep(timeToSleep * 1000000);
}
double ts = getCurrentTS(); double ts = getCurrentTS();
double delta = ts - mLastts;
/* for the fast ticked stuff */
if (delta > mTimeDelta)
{
#ifdef DEBUG_TICK
std::cerr << "Delta: " << delta << std::endl;
std::cerr << "Time Delta: " << mTimeDelta << std::endl;
std::cerr << "Avg Tick Rate: " << mAvgTickRate << std::endl;
#endif
mLastts = ts; mLastts = ts;
/******************************** RUN SERVER *****************/ // stuff we do always
// tick the core
#ifdef TICK_DEBUG
RsDbg() << "TICK_DEBUG ticking server" << std::endl;
#endif
lockRsCore(); lockRsCore();
int moreToTick = pqih->tick(); int moreToTick = pqih->tick();
#ifdef DEBUG_TICK
std::cerr << "RsServer::run() ftserver->tick(): moreToTick: " << moreToTick << std::endl;
#endif
unlockRsCore(); unlockRsCore();
// tick the managers
/* tick the Managers */ #ifdef TICK_DEBUG
RsDbg() << "TICK_DEBUG ticking mPeerMgr" << std::endl;
#endif
mPeerMgr->tick(); mPeerMgr->tick();
#ifdef TICK_DEBUG
RsDbg() << "TICK_DEBUG ticking mLinkMgr" << std::endl;
#endif
mLinkMgr->tick(); mLinkMgr->tick();
#ifdef TICK_DEBUG
RsDbg() << "TICK_DEBUG ticking mNetMgr" << std::endl;
#endif
mNetMgr->tick(); mNetMgr->tick();
/******************************** RUN SERVER *****************/
/* adjust tick rate depending on whether there is more.
*/
mAvgTickRate = 0.2 * mTimeDelta + 0.8 * mAvgTickRate; // stuff we do every second
if (ts - mCycle1 > 1)
if (1 == moreToTick)
{ {
mTimeDelta = 0.9 * mAvgTickRate; #ifdef TICK_DEBUG
if (mTimeDelta > kickLimit) RsDbg() << "TICK_DEBUG every second" << std::endl;
{ #endif
/* force next tick in one sec // slow services
* if we are reading data. if (rsPlugins)
*/ rsPlugins->slowTickPlugins((rstime_t)ts);
mTimeDelta = kickLimit; // UDP keepalive
mAvgTickRate = kickLimit; // tou_tick_stunkeepalive();
} // other stuff to tick
} // update();
else mCycle1 = ts;
{
mTimeDelta = 1.1 * mAvgTickRate;
} }
/* limiter */ // stuff we do every five seconds
if (mTimeDelta < minTimeDelta) if (ts - mCycle2 > 5)
{ {
mTimeDelta = minTimeDelta; #ifdef TICK_DEBUG
} RsDbg() << "TICK_DEBUG every 5 seconds" << std::endl;
else if (mTimeDelta > maxTimeDelta) #endif
{ // save stuff
mTimeDelta = maxTimeDelta; mConfigMgr->tick();
mCycle2 = ts;
} }
/* Fast Updates */ // stuff we do every minute
if (ts - mCycle3 > 60)
/* now we have the slow ticking stuff */
/* stuff ticked once a second (but can be slowed down) */
if ((int) ts > mLastSec)
{ {
mLastSec = (int) ts; #ifdef TICK_DEBUG
RsDbg() << "TICK_DEBUG every 60 seconds" << std::endl;
#endif
// force saving FileTransferStatus TODO
// ftserver->saveFileTransferStatus();
// see if we need to resave certs
// AuthSSL::getAuthSSL()->CheckSaveCertificates();
mCycle3 = ts;
}
// Every second! (UDP keepalive). // stuff we do every hour
//tou_tick_stunkeepalive(); if (ts - mCycle4 > 3600)
// every five loops (> 5 secs)
if (mLoop % 5 == 0)
{ {
// update_quick_stats(); #ifdef TICK_DEBUG
RsDbg() << "TICK_DEBUG every hour" << std::endl;
#endif
mCycle4 = ts;
}
// Update All Every 5 Seconds. // ticking is done, now compute new values of mLastRunDuration, mAvgRunDuration and mTickInterval
// These Update Functions do the locking themselves. ts = getCurrentTS();
#ifdef DEBUG_TICK mLastRunDuration = ts - mLastts;
std::cerr << "RsServer::run() Updates()" << std::endl; mAvgRunDuration = 0.1 * mLastRunDuration + 0.9 * mAvgRunDuration;
#ifdef TICK_DEBUG
RsDbg() << "TICK_DEBUG new mLastRunDuration " << mLastRunDuration << " mAvgRunDuration " << mAvgRunDuration << std::endl;
if (mLastRunDuration > WARN_BIG_CYCLE_TIME)
RsDbg() << "TICK_DEBUG excessively long lycle time " << mLastRunDuration << std::endl;
#endif #endif
mConfigMgr->tick(); /* saves stuff */ // if the core has returned that there is more to tick we decrease the ticking interval, else we increse it
// this should be studied closer as I dont think that the core ever returns 1
#ifdef TICK_DEBUG
RsDbg() << "TICK_DEBUG moreToTick " << moreToTick << std::endl;
#endif
if (moreToTick == 1)
mTickInterval = 0.9 * mTickInterval;
else
mTickInterval = 1.1 * mTickInterval;
#ifdef TICK_DEBUG
RsDbg() << "TICK_DEBUG new tick interval " << mTickInterval << std::endl;
#endif
} // keep the tick interval within allowed limits
if (mTickInterval < minTickInterval)
// every 60 loops (> 1 min) mTickInterval = minTickInterval;
if (++mLoop >= 60) else if (mTickInterval > maxTickInterval)
{ mTickInterval = maxTickInterval;
mLoop = 0; #ifdef TICK_DEBUG
RsDbg() << "TICK_DEBUG new tick interval after limiter " << mTickInterval << std::endl;
/* force saving FileTransferStatus TODO */
//ftserver->saveFileTransferStatus();
/* see if we need to resave certs */
//AuthSSL::getAuthSSL()->CheckSaveCertificates();
/* hour loop */
if (++mMin >= 60)
{
mMin = 0;
}
}
/* Tick slow services */
if(rsPlugins)
rsPlugins->slowTickPlugins((rstime_t)ts);
// slow update tick as well.
// update();
} // end of slow tick.
} // end of only once a second.
#ifdef DEBUG_TICK
double endCycleTs = getCurrentTS();
double cycleTime = endCycleTs - ts;
if (cycleTime > WARN_BIG_CYCLE_TIME)
{
std::string out;
rs_sprintf(out, "RsServer::run() WARNING Excessively Long Cycle Time: %g secs => Please DEBUG", cycleTime);
std::cerr << out << std::endl;
}
#endif #endif
} }

View file

@ -188,16 +188,14 @@ public:
// Worker Data..... // Worker Data.....
int mMin ; double mLastts;
int mLoop ; double mTickInterval;
int mLastts ; double mLastRunDuration;
long mLastSec ; double mAvgRunDuration;
double mAvgTickRate ; double mCycle1, mCycle2, mCycle3, mCycle4;
double mTimeDelta ;
static const double minTimeDelta; // 25; static const double minTickInterval;
static const double maxTimeDelta; static const double maxTickInterval;
static const double kickLimit;
/// @see RsControl::setShutdownCallback /// @see RsControl::setShutdownCallback
std::function<void(int)> mShutdownCallback; std::function<void(int)> mShutdownCallback;