1
0
mirror of https://github.com/pgbackrest/pgbackrest.git synced 2024-12-04 09:43:08 +02:00

Refactor Wait object to expose remaining wait as waitRemains().

This is useful for code that has its own wait mechanism, e.g. poll(), but still needs a way to track overall time elapsed.

To keep it simple waitRemains() is called by waitMore().
This commit is contained in:
David Steele 2024-10-09 17:57:52 +03:00
parent 77ae753ef5
commit 33fa396561
3 changed files with 71 additions and 44 deletions

View File

@ -54,6 +54,58 @@ waitNew(const TimeMSec waitTime)
FUNCTION_LOG_RETURN(WAIT, this);
}
/**********************************************************************************************************************************/
FN_EXTERN TimeMSec
waitRemains(Wait *const this)
{
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(WAIT, this);
FUNCTION_LOG_END();
ASSERT(this != NULL);
TimeMSec result = 0;
// If sleep is 0 then the wait time has already ended
if (this->sleepTime > 0)
{
// Get the elapsed time
const TimeMSec elapsedTime = timeMSec() - this->beginTime;
// Is there more time to go?
if (elapsedTime < this->waitTime)
{
// Calculate remaining time
result = this->waitTime - elapsedTime;
// Calculate sleep time as a sum of current and last (a Fibonacci-type sequence)
TimeMSec sleepTime = this->sleepTime + this->sleepPrevTime;
// Make sure sleep time does not go beyond remaining time (this won't be negative because of the if condition above)
if (sleepTime > result)
sleepTime = result;
// Store new sleep times
this->sleepPrevTime = this->sleepTime;
this->sleepTime = sleepTime;
}
// Else are there retries left?
else if (this->retry != 0)
{
result = this->sleepTime;
}
// Else set sleep to zero
else
this->sleepTime = 0;
// Decrement retries
if (this->retry > 0)
this->retry--;
}
FUNCTION_LOG_RETURN(TIME_MSEC, result);
}
/**********************************************************************************************************************************/
FN_EXTERN bool
waitMore(Wait *const this)
@ -66,52 +118,12 @@ waitMore(Wait *const this)
bool result = false;
// If sleep is 0 then the wait time has already ended
if (this->sleepTime > 0)
// If time remains in the wait then sleep
if (waitRemains(this) > 0)
{
// Get the elapsed time
const TimeMSec elapsedTime = timeMSec() - this->beginTime;
// Is there more time to go?
if (elapsedTime < this->waitTime)
{
// Calculate remaining sleep time
const TimeMSec remainTime = this->waitTime - elapsedTime;
// Calculate sleep time as a sum of current and last (a Fibonacci-type sequence)
TimeMSec sleepTime = this->sleepTime + this->sleepPrevTime;
// Make sure sleep time does not go beyond remaining time (this won't be negative because of the if condition above)
if (sleepTime > remainTime)
sleepTime = remainTime;
// Sleep required amount
sleepMSec(sleepTime);
// Store new sleep times
this->sleepPrevTime = this->sleepTime;
this->sleepTime = sleepTime;
}
// Else are there retries left?
else if (this->retry != 0)
{
// Sleep using the last calculated time
sleepMSec(this->sleepTime);
}
// Else set sleep to zero so call will return false
else
this->sleepTime = 0;
// Caller can continue processing
if (this->sleepTime > 0)
{
// Decrement retries
if (this->retry != 0)
this->retry--;
result = true;
}
}
FUNCTION_LOG_RETURN(BOOL, result);
}

View File

@ -25,6 +25,9 @@ FN_EXTERN Wait *waitNew(TimeMSec waitTime);
/***********************************************************************************************************************************
Functions
***********************************************************************************************************************************/
// Return the remaining time left
FN_EXTERN TimeMSec waitRemains(Wait *this);
// Wait and return true if the caller has more time/retries left
FN_EXTERN bool waitMore(Wait *this);

View File

@ -85,6 +85,18 @@ testRun(void)
TEST_RESULT_BOOL(end - begin < wait->waitTime + 1200, true, " upper range check");
TEST_RESULT_VOID(waitFree(wait), " free wait");
// -------------------------------------------------------------------------------------------------------------------------
TEST_TITLE("waitRemainder()");
TEST_ASSIGN(wait, waitNew(500), "new wait = 500ms");
TEST_RESULT_BOOL(waitRemains(wait) <= 500, true, "check initial wait remainder");
TEST_RESULT_BOOL(waitRemains(wait) > 400, true, "check initial wait remainder");
sleepMSec(100);
TEST_RESULT_BOOL(waitRemains(wait) <= 400, true, "check updated wait remainder");
TEST_RESULT_BOOL(waitRemains(wait) > 300, true, "check updated wait remainder");
}
FUNCTION_HARNESS_RETURN_VOID();