Added exponential backoff when errors occur in sicspoll

This commit is contained in:
2016-11-24 13:49:07 +01:00
parent e5ecf5218e
commit 3fda3d9864
3 changed files with 37 additions and 4 deletions

View File

@ -36,7 +36,6 @@ static int pollHdb(struct __POLLDRIV *self, SConnection * pCon)
assert(node != NULL); assert(node != NULL);
self->nextPoll = time(NULL) + self->pollIntervall;
if (GetHipadabaPar(node, &newVal, pCon) == 1) { if (GetHipadabaPar(node, &newVal, pCon) == 1) {
ReleaseHdbValue(&newVal); ReleaseHdbValue(&newVal);
return 1; return 1;
@ -84,7 +83,6 @@ static int pollScript(struct __POLLDRIV *self, SConnection * pCon)
int status; int status;
Tcl_Interp *pTcl = InterpGetTcl(pServ->pSics); Tcl_Interp *pTcl = InterpGetTcl(pServ->pSics);
self->nextPoll = time(NULL) + self->pollIntervall;
MacroPush(pCon); MacroPush(pCon);
status = Tcl_Eval(pTcl, (char *) self->objPointer); status = Tcl_Eval(pTcl, (char *) self->objPointer);

View File

@ -16,6 +16,7 @@ typedef struct __POLLDRIV {
void *objPointer; /* a pointer to the object */ void *objPointer; /* a pointer to the object */
time_t nextPoll; /* next polling time */ time_t nextPoll; /* next polling time */
int pollIntervall; /* poll intervall */ int pollIntervall; /* poll intervall */
int actualPollIntervall; /* for supporting exponential backoff */
int (*isDue) (struct __POLLDRIV * self, time_t now, SConnection * pCon); int (*isDue) (struct __POLLDRIV * self, time_t now, SConnection * pCon);
/* function called to determine if this object must be polled */ /* function called to determine if this object must be polled */
int (*poll) (struct __POLLDRIV * self, SConnection * pCon); int (*poll) (struct __POLLDRIV * self, SConnection * pCon);

View File

@ -9,6 +9,11 @@
* Copyright: see COPYRIGHT * Copyright: see COPYRIGHT
* *
* Mark Koennecke, November-December 2006 * 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 <stdlib.h> #include <stdlib.h>
@ -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) static int PollTask(void *data)
{ {
@ -141,7 +172,8 @@ static int PollTask(void *data)
poll = (pPollDriv) LLDnodePtr(self->pollList); poll = (pPollDriv) LLDnodePtr(self->pollList);
if (status != 0 && poll != NULL) { if (status != 0 && poll != NULL) {
if (poll->isDue(poll, now, self->pCon)) { 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; return 0;
} }
driv->pollIntervall = iVal; driv->pollIntervall = iVal;
driv->actualPollIntervall = iVal;
SCSendOK(pCon); SCSendOK(pCon);
return 1; return 1;
} else { } else {
@ -346,6 +379,7 @@ int SICSPollWrapper(SConnection * pCon, SicsInterp * pSics, void *pData,
return 0; return 0;
} }
status = driv->poll(driv, pCon); status = driv->poll(driv, pCon);
advancePoll(driv,status);
if (status != 1) { if (status != 1) {
SCWrite(pCon, "ERROR: polling object", eError); SCWrite(pCon, "ERROR: polling object", eError);
return 0; return 0;