The application now pings many hosts in parallel
authorGuilherme Maciel Ferreira <guilherme.maciel.ferreira@intra2net.com>
Tue, 8 Mar 2011 17:56:29 +0000 (18:56 +0100)
committerGuilherme Maciel Ferreira <guilherme.maciel.ferreira@intra2net.com>
Tue, 8 Mar 2011 17:56:29 +0000 (18:56 +0100)
- uses an asynchronous approach, based on boost::asio::io_service::run() loop and asynchronous timers

conf/pingcheck.conf
src/main.cpp
src/ping/pingcheck.cpp
src/ping/pingcheck.h

index d9ed170..642876d 100644 (file)
@@ -2,12 +2,12 @@ limit-to-notify=5
 
 [host]
 name=www.intra2net.com
-interval=4
+interval=30
 
 [host]
-name=209.85.148.105
-interval=2
+name=www.google.com
+interval=5
 
 [host]
 name=www.ufsc.br
-interval=3
+interval=60
index 8e4bdde..43db4c7 100644 (file)
@@ -1,3 +1,4 @@
+#include <boost/asio.hpp>
 #include <boost/foreach.hpp>
 #include <vector>
 
@@ -6,6 +7,7 @@
 #include "pingcheck.h"
 
 using namespace std;
+using namespace boost::asio;
 
 int main( int argc, char* argv[] )
 {
@@ -13,13 +15,24 @@ int main( int argc, char* argv[] )
     bool read_success = config_reader.parse( argc, argv );
     if ( read_success )
     {
+        io_service io_service;
+
         Configuration config = config_reader.get_configuration();
-        vector<HostItem> hosts = config.get_hosts();
+        vector< HostItem > hosts = config.get_hosts();
+        vector< PingCheckItem > check_list;
         BOOST_FOREACH( HostItem host, hosts )
         {
-            PingCheck check( *host );
-            check.start_pinging();
+            PingCheckItem check( new PingCheck( io_service, *host ) );
+            check_list.push_back( check );
         }
+
+        BOOST_FOREACH( PingCheckItem check, check_list )
+        {
+            check->start_pinging();
+        }
+
+        // Main loop to handle ping requests when they were scheduled
+        io_service.run();
     }
 
     return 0;
index d7b1bd5..9551d16 100644 (file)
@@ -1,4 +1,4 @@
-#include <boost/asio.hpp>
+#include <boost/bind.hpp>
 #include <iostream>
 
 #include "boostpinger.h"
@@ -7,13 +7,20 @@
 
 using namespace std;
 using namespace boost::asio;
+using namespace boost::posix_time;
 
 //-----------------------------------------------------------------------------
 // PingCheck
 //-----------------------------------------------------------------------------
 
-PingCheck::PingCheck( const Host &host ) :
-    Host_( host )
+PingCheck::PingCheck(
+        boost::asio::io_service &io_service,
+        const Host &host
+) :
+    IoService( io_service ),
+    Timer( io_service ),
+    TimeSentLastPing( microsec_clock::universal_time() ),
+    DestinationHost( host )
 {
 }
 
@@ -23,45 +30,47 @@ PingCheck::~PingCheck()
 
 void PingCheck::start_pinging()
 {
-    string destination = Host_.get_address();
-    uint ping_set_total = 3; // TODO configurable:
+    string destination = DestinationHost.get_address();
+    uint ping_set_total = 1; // TODO configurable:
     uint ping_set_count = 0;
     while ( ping_set_count < ping_set_total )
     {
-        ping_and_wait( destination );
+        ping( destination );
 
         ping_set_count++;
     }
 }
 
-void PingCheck::ping_and_wait( const string &destination )
+void PingCheck::ping( const string &destination )
 {
-    try
-    {
-        ping( destination );
+    BOOST_ASSERT( !destination.empty() );
 
-        wait();
-    }
-    catch ( exception& e )
-    {
-        cerr << "Exception: " << e.what() << endl;
-        return;
-    }
-}
-
-void PingCheck::ping( const string &destination ) throw ( exception& )
-{
-    uint times_to_ping = 3; // TODO configurable: this must be automatically selected
+    uint times_to_ping = 1; // TODO configurable: this must be automatically selected
     boost::asio::io_service io_service;
     BoostPinger pinger( io_service );
     pinger.ping( destination, times_to_ping );
+
+    update_ping_statistics();
+
+    schedule_next_ping();
 }
 
-void PingCheck::wait()
+void PingCheck::update_ping_statistics()
 {
-    boost::asio::io_service io_service;
-    deadline_timer timer( io_service );
-    uint interval = Host_.get_interval(); // TODO configurable:
-    timer.expires_from_now( boost::posix_time::seconds( interval ) );
-    timer.wait();
+    ptime now = microsec_clock::universal_time(); // TODO
+    cerr << "- Time elapsed since last ping = "
+         << (now - TimeSentLastPing).total_seconds() << "s" << endl; // TODO
+    TimeSentLastPing = microsec_clock::universal_time(); // TODO
+}
+
+void PingCheck::schedule_next_ping()
+{
+    uint interval = DestinationHost.get_interval(); // TODO configurable:
+    Timer.expires_from_now( seconds( interval ) );
+    Timer.async_wait( boost::bind( &PingCheck::handle_next_ping, this ) );
+}
+
+void PingCheck::handle_next_ping()
+{
+    start_pinging();
 }
index 6c940e2..e733385 100644 (file)
@@ -1,6 +1,8 @@
 #ifndef PINGCHECK_H
 #define PINGCHECK_H
 
+#include <boost/asio.hpp>
+#include <boost/shared_ptr.hpp>
 #include <string>
 
 #include "host.h"
 class PingCheck
 {
 public:
-    PingCheck( const Host &host );
+    PingCheck(
+            boost::asio::io_service &io_service,
+            const Host &host
+    );
     virtual ~PingCheck();
 
     void start_pinging();
 
 private:
-    void ping_and_wait( const std::string &destination );
-    void ping( const std::string &destination ) throw ( std::exception& );
-    void wait();
+    void ping( const std::string &destination );
+    void update_ping_statistics();
+    void schedule_next_ping();
+    void handle_next_ping();
 
 private:
-    Host Host_;
+    boost::asio::io_service &IoService;
+    boost::asio::deadline_timer Timer;
+    boost::posix_time::ptime TimeSentLastPing;
+    Host DestinationHost;
 
 };
 
+//-----------------------------------------------------------------------------
+// PingCheckItem
+//-----------------------------------------------------------------------------
+
+typedef boost::shared_ptr<PingCheck> PingCheckItem;
+
 #endif /* PINGCHECK_H */