- PingAnalyzer::exceeded_ping_failed_count_limit() made public, thus the Analyzer can check when is required to speed up the ping (or back to the original interval)
- Included a PingInterval template class to hide the computation logic of interval speed up and slow down
LimitPingFailPercentage( limit_ping_fail_percentage ),
ResolvedIpCount( 0 ),
PingsPerformedCount( 0 ),
- PingsFailedCount( 0 )
+ PingsFailedCount( 0 ),
+ ExceededPingFailedCountLimit( false )
{
BOOST_ASSERT( !host_address.empty() );
BOOST_ASSERT( ( 0 <= limit_ping_fail_percentage ) && ( limit_ping_fail_percentage <= 100 ) );
ResolvedIpCount = resolved_ip_count;
}
+bool PingAnalyzer::exceeded_ping_failed_count_limit() const
+{
+ return ExceededPingFailedCountLimit;
+}
+
void PingAnalyzer::update_ping_statistics( bool ping_success )
{
BOOST_ASSERT( 1 <= ResolvedIpCount );
// failed
if ( tried_all_resolved_ip() )
{
- analyze();
+ analyze_ping_statistics();
reset_ping_counters();
}
BOOST_ASSERT( PingsFailedCount <= PingsPerformedCount );
}
-void PingAnalyzer::analyze()
+bool PingAnalyzer::tried_all_resolved_ip() const
+{
+ return ( PingsPerformedCount >= ResolvedIpCount );
+}
+
+void PingAnalyzer::analyze_ping_statistics()
{
BOOST_ASSERT( PingsPerformedCount == ResolvedIpCount );
BOOST_ASSERT( !HostAddress.empty() );
{
++PingsFailedCount;
+ update_ping_failed_statistics();
+
BOOST_ASSERT( ( 0 <= PingsFailedCount ) && ( PingsFailedCount <= PingsPerformedCount ) );
}
-bool PingAnalyzer::exceeded_ping_failed_count_limit() const
+void PingAnalyzer::update_ping_failed_statistics()
{
BOOST_ASSERT( ( 0 <= LimitPingFailPercentage ) && ( LimitPingFailPercentage <= 100 ) );
BOOST_ASSERT( ( 0 <= PingsFailedCount ) && ( PingsFailedCount <= PingsPerformedCount ) );
int limit_ping_fail_absolute = LimitPingFailPercentage / 100; // TODO possible precision loss, check with care
- return ( PingsFailedCount > limit_ping_fail_absolute );
-}
-
-bool PingAnalyzer::tried_all_resolved_ip() const
-{
- return ( PingsPerformedCount >= ResolvedIpCount );
+ ExceededPingFailedCountLimit = ( PingsFailedCount > limit_ping_fail_absolute );
}
virtual ~PingAnalyzer();
void set_resolved_ip_count( const int resolved_ip_count );
+ bool exceeded_ping_failed_count_limit() const;
void update_ping_statistics( bool ping_success );
private:
- void analyze();
+ bool tried_all_resolved_ip() const;
+ void analyze_ping_statistics();
void reset_ping_counters();
void increase_ping_performed_count();
void increase_ping_failed_count();
- bool exceeded_ping_failed_count_limit() const;
- bool tried_all_resolved_ip() const;
+ void update_ping_failed_statistics();
private:
std::string HostAddress;
int ResolvedIpCount;
int PingsPerformedCount;
int PingsFailedCount;
+ bool ExceededPingFailedCountLimit;
};
--- /dev/null
+#ifndef PINGINTERVAL_H
+#define PINGINTERVAL_H
+
+//-----------------------------------------------------------------------------
+// PingInterval
+//-----------------------------------------------------------------------------
+
+/**
+ * @brief Class designed to behave like a scalar type (i.e. int, long), but
+ * with helper methods to encapsulate interval computation.
+ * Scope: one object per host.
+ */
+template<typename T>
+class PingInterval
+{
+public:
+ PingInterval( T interval );
+
+ operator T();
+
+ void back_to_original();
+ void speed_up();
+
+private:
+ bool can_speed_up() const;
+
+private:
+ const T OriginalInterval;
+ T Interval;
+
+};
+
+
+template<typename T>
+ PingInterval<T>::PingInterval(
+ T interval
+ ) :
+ OriginalInterval( interval ),
+ Interval( interval )
+ {
+ }
+
+template<typename T>
+ PingInterval<T>::operator T()
+ {
+ return Interval;
+ }
+
+template<typename T>
+ void PingInterval<T>::back_to_original()
+ {
+ Interval = OriginalInterval;
+ }
+
+template<typename T>
+ void PingInterval<T>::speed_up()
+ {
+ if ( can_speed_up() )
+ Interval = Interval / 2;
+ }
+
+template<typename T>
+ bool PingInterval<T>::can_speed_up() const
+ {
+ T half_original = OriginalInterval / 2;
+
+ return (Interval > half_original);
+ }
+
+
+#endif /* PINGINTERVAL_H */
void PingScheduler::update_ping_statistics( const bool ping_success )
{
Analyzer.update_ping_statistics( ping_success );
+
+ // TODO FIX this method, once it has a semantic dependency with the
+ // update_ping_statistics method, because it depends on the PingeAnalyzer
+ // statistics to update the exceeded_ping_failed_count_limit
+ update_ping_interval();
+}
+
+void PingScheduler::update_ping_interval()
+{
+ // must to ping more often?
+ if ( Analyzer.exceeded_ping_failed_count_limit() )
+ {
+ PingIntervalInSec.speed_up();
+
+ cout << "- Speeding up ping interval to: " << PingIntervalInSec
+ << "s" << endl; // TODO output log
+ }
+ else
+ {
+ PingIntervalInSec.back_to_original();
+
+ cout << "- Stick to the original ping interval: " << PingIntervalInSec
+ << "s" << endl; // TODO output log
+ }
}
void PingScheduler::update_ping_elapsed_time()
{
ptime now = microsec_clock::universal_time();
- cerr << "- Time elapsed since last ping: "
- << (now - TimeSentLastPing).total_seconds() << "s" << endl; // TODO reformat this message
+ cout << "- Time elapsed since last ping: "
+ << (now - TimeSentLastPing).total_seconds() << "s"
+ << endl; // TODO output log
TimeSentLastPing = microsec_clock::universal_time();
}
#include "dns/dnsresolver.h"
#include "ping/pinganalyzer.h"
+#include "ping/pinginterval.h"
class StatusNotifier;
void schedule_next_ping();
void handle_next_ping();
void update_ping_statistics( const bool ping_success );
+ void update_ping_interval();
void update_ping_elapsed_time();
private:
boost::asio::io_service &IoService;
boost::asio::deadline_timer Timer;
boost::posix_time::ptime TimeSentLastPing;
- const long PingIntervalInSec;
+ PingInterval<long> PingIntervalInSec;
DnsResolver IpList;
PingAnalyzer Analyzer;