Browse Source

[2781] implement skipping collecting and polling statistics to stats

The stats module logs STATS_SKIP_POLLING when it catches an InitSessionTimeout
exception while initially receiving modules information from the init
module. Also, the stats module logs STATS_SKIP_COLLECTING including the name of
the module unable to collect when it catches a SessionTimeout exception while
collecting statistics from that module.
Naoki Kambe 11 years ago
parent
commit
c185e03598
2 changed files with 42 additions and 6 deletions
  1. 17 6
      src/bin/stats/stats.py.in
  2. 25 0
      src/bin/stats/tests/stats_test.py

+ 17 - 6
src/bin/stats/stats.py.in

@@ -186,6 +186,11 @@ class StatsError(Exception):
     """Exception class for Stats class"""
     """Exception class for Stats class"""
     pass
     pass
 
 
+class InitSessionTimeout(isc.cc.session.SessionTimeout):
+    """SessionTimeout Exception in the session between the stats module and the
+    init module"""
+    pass
+
 class Stats:
 class Stats:
     """
     """
     Main class of stats module
     Main class of stats module
@@ -271,6 +276,8 @@ class Stats:
             # TODO: Is it OK to just pass? As part of refactoring, preserving
             # TODO: Is it OK to just pass? As part of refactoring, preserving
             # the original behaviour.
             # the original behaviour.
             value = None
             value = None
+        except isc.cc.session.SessionTimeout as e:
+            raise InitSessionTimeout(e)
         modules = []
         modules = []
         if type(value) is list:
         if type(value) is list:
             # NOTE: For example, the "show_processes" command
             # NOTE: For example, the "show_processes" command
@@ -338,6 +345,7 @@ class Stats:
         _statistics_data = []
         _statistics_data = []
         _sequences = sequences[:]
         _sequences = sequences[:]
         while len(_sequences) > 0:
         while len(_sequences) > 0:
+            (module_name, seq) = (None, None)
             try:
             try:
                 (module_name, seq) = _sequences.pop(0)
                 (module_name, seq) = _sequences.pop(0)
                 answer, env = self.cc_session.group_recvmsg(False, seq)
                 answer, env = self.cc_session.group_recvmsg(False, seq)
@@ -348,7 +356,7 @@ class Stats:
                             (module_name, env['from'], args))
                             (module_name, env['from'], args))
             # skip this module if SessionTimeout raised
             # skip this module if SessionTimeout raised
             except isc.cc.session.SessionTimeout:
             except isc.cc.session.SessionTimeout:
-                pass
+                logger.warn(STATS_SKIP_COLLECTING, module_name)
         return _statistics_data
         return _statistics_data
 
 
     def _refresh_statistics(self, statistics_data):
     def _refresh_statistics(self, statistics_data):
@@ -371,11 +379,14 @@ class Stats:
            search multiple instances of same module. Second requests
            search multiple instances of same module. Second requests
            each module to invoke 'getstats'. Finally updates internal
            each module to invoke 'getstats'. Finally updates internal
            statistics data every time it gets from each instance."""
            statistics data every time it gets from each instance."""
-        modules = self._get_multi_module_list()
-        sequences = self._query_statistics(modules)
-        _statistics_data = self._collect_statistics(sequences)
-        self._refresh_statistics(_statistics_data)
-        # if successfully done, set the last time of polling
+        try:
+            modules = self._get_multi_module_list()
+            sequences = self._query_statistics(modules)
+            _statistics_data = self._collect_statistics(sequences)
+            self._refresh_statistics(_statistics_data)
+        except InitSessionTimeout:
+            logger.warn(STATS_SKIP_POLLING)
+        # if successfully done or skipped, set the last time of polling
         self._lasttime_poll = get_timestamp()
         self._lasttime_poll = get_timestamp()
 
 
     def _check_command(self, nonblock=False):
     def _check_command(self, nonblock=False):

+ 25 - 0
src/bin/stats/tests/stats_test.py

@@ -1383,6 +1383,16 @@ class TestStats(unittest.TestCase):
         stat.mccs.rpc_call = lambda x,y: __raise(99, 'Error')
         stat.mccs.rpc_call = lambda x,y: __raise(99, 'Error')
         self.assertListEqual([], stat._get_multi_module_list())
         self.assertListEqual([], stat._get_multi_module_list())
 
 
+    def test_get_multi_module_list_initsessiontimeout(self):
+        """Test _get_multi_module_list() returns an empty list if rcp_call()
+        raise a InitSeeionTimeout exception"""
+        # InitSeeionTimeout case
+        stat = MyStats()
+        ex = stats.InitSessionTimeout
+        def __raise(*x): raise ex(*x)
+        stat.mccs.rpc_call = lambda x,y: __raise()
+        self.assertRaises(ex, stat._get_multi_module_list)
+
     def test_query_statistics(self):
     def test_query_statistics(self):
         """Test _query_statistics returns a list of pairs of module and
         """Test _query_statistics returns a list of pairs of module and
         sequences from group_sendmsg()"""
         sequences from group_sendmsg()"""
@@ -1613,6 +1623,21 @@ class TestStats(unittest.TestCase):
         self.assertEqual(self.const_timestamp, stat._lasttime_poll)
         self.assertEqual(self.const_timestamp, stat._lasttime_poll)
         stats.get_timestamp = orig_get_timestamp
         stats.get_timestamp = orig_get_timestamp
 
 
+    def test_polling_initsessiontimeout(self):
+        """Test _lasttime_poll is updated after do_polling() in case that it catches
+        InitSesionTimeout at _get_multi_module_list()
+        """
+        orig_get_timestamp = stats.get_timestamp
+        stats.get_timestamp = lambda : self.const_timestamp
+        ex = stats.InitSessionTimeout
+        def __raise(*x): raise ex(*x)
+        stat = MyStats()
+        self.assertEqual(0.0, stat._lasttime_poll)
+        stat._get_multi_module_list = lambda: __raise()
+        stat.do_polling()
+        self.assertEqual(self.const_timestamp, stat._lasttime_poll)
+        stats.get_timestamp = orig_get_timestamp
+
 class Z_TestOSEnv(unittest.TestCase):
 class Z_TestOSEnv(unittest.TestCase):
     # Running this test would break logging setting.  To prevent it from
     # Running this test would break logging setting.  To prevent it from
     # affecting other tests we use the same workaround as Z_TestOSEnv in
     # affecting other tests we use the same workaround as Z_TestOSEnv in