diff --git a/src/cas/generic/beaconAnomalyGovernor.cpp b/src/cas/generic/beaconAnomalyGovernor.cpp new file mode 100644 index 000000000..2a83f2d45 --- /dev/null +++ b/src/cas/generic/beaconAnomalyGovernor.cpp @@ -0,0 +1,83 @@ + +/*************************************************************************\ +* Copyright (c) 2002 The University of Chicago, as Operator of Argonne +* National Laboratory. +* Copyright (c) 2002 The Regents of the University of California, as +* Operator of Los Alamos National Laboratory. +* EPICS BASE Versions 3.13.7 +* and higher are distributed subject to a Software License Agreement found +* in file LICENSE that is included with this distribution. +\*************************************************************************/ +/* + * $Id$ + * + * Author Jeffrey O. Hill + * johill@lanl.gov + * 505 665 1831 + */ + +#include "beaconAnomalyGovernor.h" +#include "beaconTimer.h" +#include "server.h" + +// +// the minimum period between beacon anomalies +// ------------------------------------------- +// +// o Gateways imply a tradeoff towards less traffic while +// paying a price of a less tightly coupled environment. +// Therefore, clients should not expect instant reconnects +// when a server is rebooted on the other side of a gateway. +// +// o In a quiescent system servers should not need to be +// rebooted and network connectivity should be constant. +// +// o Clients will keep trying to reach channels for around +// 15 min after the last beacon anomaly was seen. +// +// o The exponential backoff mechanism in the beacon timer +// ensures that clients will detect beacon anomalies +// continuously for around 30 seconds after each beacon +// anomaly is requested. +// +static const double CAServerMinBeaconAnomalyPeriod = 60.0 * 5.0; // seconds + +beaconAnomalyGovernor::beaconAnomalyGovernor ( caServerI & casIn ) : + timer ( fileDescriptorManager.createTimer () ), cas ( casIn ), + anomalyPending ( false ) +{ +} + +beaconAnomalyGovernor::~beaconAnomalyGovernor() +{ +} + +void beaconAnomalyGovernor::start () +{ + // order of operations here impacts thread safety + this->anomalyPending = true; + epicsTimer::expireInfo expInfo = this->timer.getExpireInfo (); + if ( ! expInfo.active ) { + this->cas.beaconTmr.generateBeaconAnomaly (); + this->timer.start ( *this, CAServerMinBeaconAnomalyPeriod ); + this->anomalyPending = false; + } +} + +epicsTimerNotify::expireStatus beaconAnomalyGovernor::expire ( const epicsTime & currentTime ) +{ + if ( this->anomalyPending ) { + this->anomalyPending = false; + this->cas.beaconTmr.generateBeaconAnomaly (); + } + return noRestart; +} + +void beaconAnomalyGovernor::show ( unsigned level ) const +{ + printf ( "beaconAnomalyGovernor: anomalyPending = %s\n", + this->anomalyPending ? "T": "F" ); + if ( level ) { + this->timer.show ( level - 1 ); + } +} diff --git a/src/cas/generic/beaconAnomalyGovernor.h b/src/cas/generic/beaconAnomalyGovernor.h new file mode 100644 index 000000000..6fdcec81d --- /dev/null +++ b/src/cas/generic/beaconAnomalyGovernor.h @@ -0,0 +1,43 @@ + +/*************************************************************************\ +* Copyright (c) 2002 The University of Chicago, as Operator of Argonne +* National Laboratory. +* Copyright (c) 2002 The Regents of the University of California, as +* Operator of Los Alamos National Laboratory. +* EPICS BASE Versions 3.13.7 +* and higher are distributed subject to a Software License Agreement found +* in file LICENSE that is included with this distribution. +\*************************************************************************/ +/* + * $Id$ + * + * Author Jeffrey O. Hill + * johill@lanl.gov + * 505 665 1831 + */ + +#ifndef beaconAnomalyGovernorh +#define beaconAnomalyGovernorh + +#include "epicsTimer.h" +#include "epicsMutex.h" + +class caServerI; + +class beaconAnomalyGovernor : public epicsTimerNotify { +public: + beaconAnomalyGovernor ( caServerI & ); + virtual ~beaconAnomalyGovernor(); + void start (); + void show ( unsigned level ) const; +private: + // has been checked for thread safety + epicsTimer & timer; + class caServerI & cas; + bool anomalyPending; + expireStatus expire( const epicsTime & currentTime ); + beaconAnomalyGovernor ( const beaconAnomalyGovernor & ); + beaconAnomalyGovernor & operator = ( const beaconAnomalyGovernor & ); +}; + +#endif // ifdef beaconAnomalyGovernorh \ No newline at end of file diff --git a/src/cas/generic/beaconTimer.cpp b/src/cas/generic/beaconTimer.cpp new file mode 100644 index 000000000..b4623e93d --- /dev/null +++ b/src/cas/generic/beaconTimer.cpp @@ -0,0 +1,87 @@ + +/*************************************************************************\ +* Copyright (c) 2002 The University of Chicago, as Operator of Argonne +* National Laboratory. +* Copyright (c) 2002 The Regents of the University of California, as +* Operator of Los Alamos National Laboratory. +* EPICS BASE Versions 3.13.7 +* and higher are distributed subject to a Software License Agreement found +* in file LICENSE that is included with this distribution. +\*************************************************************************/ +/* + * $Id$ + * + * Author Jeffrey O. Hill + * johill@lanl.gov + * 505 665 1831 + */ + +#include "server.h" +#include "beaconTimer.h" + +// the maximum beacon period if EPICS_CA_BEACON_PERIOD isnt available +static const double CAServerMaxBeaconPeriod = 15.0; // seconds + +// the initial beacon period +static const double CAServerMinBeaconPeriod = 1.0e-3; // seconds + +beaconTimer::beaconTimer ( caServerI & casIn ) : + timer ( fileDescriptorManager.createTimer() ), + cas ( casIn ), + beaconPeriod ( CAServerMinBeaconPeriod ), + maxBeaconInterval ( CAServerMaxBeaconPeriod ), + beaconCounter ( 0U ) +{ + caStatus status; + double maxPeriod; + + if ( envGetConfigParamPtr ( & EPICS_CAS_BEACON_PERIOD ) ) { + status = envGetDoubleConfigParam ( & EPICS_CAS_BEACON_PERIOD, & maxPeriod ); + } + else { + status = envGetDoubleConfigParam ( & EPICS_CA_BEACON_PERIOD, & maxPeriod ); + } + if ( status || maxPeriod <= 0.0 ) { + errlogPrintf ( + "EPICS \"%s\" float fetch failed\n", EPICS_CAS_BEACON_PERIOD.name ); + errlogPrintf ( + "Setting \"%s\" = %f\n", EPICS_CAS_BEACON_PERIOD.name, + this->maxBeaconInterval); + } + else { + this->maxBeaconInterval = maxPeriod; + } + + this->timer.start ( *this, CAServerMinBeaconPeriod ); +} + +beaconTimer::~beaconTimer () +{ + this->timer.destroy (); +} + +void beaconTimer::generateBeaconAnomaly () +{ + this->beaconPeriod = CAServerMinBeaconPeriod; + this->timer.start ( *this, CAServerMinBeaconPeriod ); +} + + +epicsTimerNotify::expireStatus beaconTimer::expire( const epicsTime & /* currentTime */ ) +{ + this->cas.sendBeacon ( this->beaconCounter ); + + this->beaconCounter++; + + // double the period between beacons (but dont exceed max) + if ( this->beaconPeriod < this->maxBeaconInterval ) { + this->beaconPeriod += this->beaconPeriod; + + if ( this->beaconPeriod >= this->maxBeaconInterval ) { + this->beaconPeriod = this->maxBeaconInterval; + } + } + + return expireStatus ( restart, this->beaconPeriod ); +} + diff --git a/src/cas/generic/beaconTimer.h b/src/cas/generic/beaconTimer.h new file mode 100644 index 000000000..6b88833ba --- /dev/null +++ b/src/cas/generic/beaconTimer.h @@ -0,0 +1,47 @@ + +/*************************************************************************\ +* Copyright (c) 2002 The University of Chicago, as Operator of Argonne +* National Laboratory. +* Copyright (c) 2002 The Regents of the University of California, as +* Operator of Los Alamos National Laboratory. +* EPICS BASE Versions 3.13.7 +* and higher are distributed subject to a Software License Agreement found +* in file LICENSE that is included with this distribution. +\*************************************************************************/ +/* + * $Id$ + * + * Author Jeffrey O. Hill + * johill@lanl.gov + * 505 665 1831 + */ + +#ifndef beaconTimerh +#define beaconTimerh + +#include "epicsTimer.h" +#include "caProto.h" + +class caServerI; + +// +// beaconTimer +// +class beaconTimer : public epicsTimerNotify { +public: + beaconTimer ( caServerI & casIn ); + virtual ~beaconTimer (); + void generateBeaconAnomaly (); +private: + // has been checked for thread safety + epicsTimer & timer; + caServerI & cas; + double beaconPeriod; + double maxBeaconInterval; + ca_uint32_t beaconCounter; + expireStatus expire ( const epicsTime & currentTime ); + beaconTimer ( const beaconTimer & ); + beaconTimer & operator = ( const beaconTimer & ); +}; + +#endif // ifdef beaconTimerh \ No newline at end of file