From 3fda3d9864d6f365eb2b0fb87ecc5ea098d3bfdc Mon Sep 17 00:00:00 2001 From: koennecke Date: Thu, 24 Nov 2016 13:49:07 +0100 Subject: [PATCH] Added exponential backoff when errors occur in sicspoll --- polldriv.c | 2 -- polldriv.h | 1 + sicspoll.c | 38 ++++++++++++++++++++++++++++++++++++-- 3 files changed, 37 insertions(+), 4 deletions(-) diff --git a/polldriv.c b/polldriv.c index de89f650..ce27b387 100644 --- a/polldriv.c +++ b/polldriv.c @@ -36,7 +36,6 @@ static int pollHdb(struct __POLLDRIV *self, SConnection * pCon) assert(node != NULL); - self->nextPoll = time(NULL) + self->pollIntervall; if (GetHipadabaPar(node, &newVal, pCon) == 1) { ReleaseHdbValue(&newVal); return 1; @@ -84,7 +83,6 @@ static int pollScript(struct __POLLDRIV *self, SConnection * pCon) int status; Tcl_Interp *pTcl = InterpGetTcl(pServ->pSics); - self->nextPoll = time(NULL) + self->pollIntervall; MacroPush(pCon); status = Tcl_Eval(pTcl, (char *) self->objPointer); diff --git a/polldriv.h b/polldriv.h index 3100dba0..5ca12ca1 100644 --- a/polldriv.h +++ b/polldriv.h @@ -16,6 +16,7 @@ typedef struct __POLLDRIV { void *objPointer; /* a pointer to the object */ time_t nextPoll; /* next polling time */ int pollIntervall; /* poll intervall */ + int actualPollIntervall; /* for supporting exponential backoff */ int (*isDue) (struct __POLLDRIV * self, time_t now, SConnection * pCon); /* function called to determine if this object must be polled */ int (*poll) (struct __POLLDRIV * self, SConnection * pCon); diff --git a/sicspoll.c b/sicspoll.c index 33be09ff..c26f93af 100644 --- a/sicspoll.c +++ b/sicspoll.c @@ -9,6 +9,11 @@ * Copyright: see COPYRIGHT * * Mark Koennecke, November-December 2006 + * + * Implemented exponential backoff up to 6 minutes when polling fails. This in order to + * reduce the number of error messages in the logs if something is MIA + * + * Mark Koennecke, November 2016 */ #include @@ -109,7 +114,33 @@ void SicsPollSignal(void *pData, int iSignal, void *pSigData) } } } - +/*---------------------------------------------------------------------- +This function implements the exponential backoff when there is a failure +in polling +------------------------------------------------------------------------*/ +static void advancePoll(pPollDriv poll, int status) +{ + if(status == 1) { + /* success */ + poll->actualPollIntervall = poll->pollIntervall; + } else { + /* + poll error, backoff + */ + if(poll->actualPollIntervall < poll->pollIntervall){ + poll->actualPollIntervall = 2 * poll->pollIntervall; + } else { + poll->actualPollIntervall = 2 * poll->actualPollIntervall; + /* + poll at least every 6 minutes + */ + if(poll->actualPollIntervall > 360){ + poll->actualPollIntervall = 360; + } + } + } + poll->nextPoll = time(NULL) + poll->actualPollIntervall; +} /*----------------------------------------------------------------------*/ static int PollTask(void *data) { @@ -141,7 +172,8 @@ static int PollTask(void *data) poll = (pPollDriv) LLDnodePtr(self->pollList); if (status != 0 && poll != NULL) { if (poll->isDue(poll, now, self->pCon)) { - poll->poll(poll, self->pCon); + status = poll->poll(poll, self->pCon); + advancePoll(poll,status); } } } @@ -312,6 +344,7 @@ int SICSPollWrapper(SConnection * pCon, SicsInterp * pSics, void *pData, return 0; } driv->pollIntervall = iVal; + driv->actualPollIntervall = iVal; SCSendOK(pCon); return 1; } else { @@ -346,6 +379,7 @@ int SICSPollWrapper(SConnection * pCon, SicsInterp * pSics, void *pData, return 0; } status = driv->poll(driv, pCon); + advancePoll(driv,status); if (status != 1) { SCWrite(pCon, "ERROR: polling object", eError); return 0;