Commit a969883c authored by JINMEI Tatuya's avatar JINMEI Tatuya
Browse files

[2244] introduced a new "Failed" state of Component.

parent 214377d8
......@@ -45,6 +45,7 @@ COMPONENT_RESTART_DELAY = 10
STATE_DEAD = 'dead'
STATE_STOPPED = 'stopped'
STATE_FAILED = 'failed'
STATE_RUNNING = 'running'
def get_signame(signal_number):
......@@ -68,6 +69,7 @@ class BaseComponent:
explicitly).
- Running - after start() was called, it started successfully and is
now running.
- Failed - the component failed (crashed) and is waiting for a restart
- Dead - it failed and can not be resurrected.
Init
......@@ -79,11 +81,11 @@ class BaseComponent:
| | |
|failure | failed() |
| | |
v | |
v | | start()/restart()
+<-----------+ |
| |
| kind == dispensable or kind|== needed and failed late
+-----------------------------+
+-----------------------> Failed
|
| kind == core or kind == needed and it failed too soon
v
......@@ -236,7 +238,7 @@ class BaseComponent:
exit_str)
if not self.running():
raise ValueError("Can't fail component that isn't running")
self.__state = STATE_STOPPED
self.__state = STATE_FAILED
self._failed_internal()
# If it is a core component or the needed component failed to start
# (including it stopped really soon)
......@@ -296,6 +298,15 @@ class BaseComponent:
"""
return self.__state == STATE_RUNNING
def is_failed(self):
"""Informs if the component has failed and is waiting for a restart.
Unlike the case of running(), if this returns True it always means
the corresponding process has died and not yet restarted.
"""
return self.__state == STATE_FAILED
def _start_internal(self):
"""
This method does the actual starting of a process. You need to override
......
......@@ -192,6 +192,7 @@ class ComponentTests(BossUtils, unittest.TestCase):
self.assertFalse(self.__stop_called)
self.assertFalse(self.__failed_called)
self.assertFalse(component.running())
self.assertFalse(component.is_failed())
# We can't stop or fail the component yet
self.assertRaises(ValueError, component.stop)
self.assertRaises(ValueError, component.failed, 1)
......@@ -205,6 +206,7 @@ class ComponentTests(BossUtils, unittest.TestCase):
self.assertFalse(self.__stop_called)
self.assertFalse(self.__failed_called)
self.assertTrue(component.running())
self.assertFalse(component.is_failed())
def __check_dead(self, component):
"""
......@@ -216,6 +218,7 @@ class ComponentTests(BossUtils, unittest.TestCase):
self.assertTrue(self.__failed_called)
self.assertEqual(1, self._exitcode)
self.assertFalse(component.running())
self.assertFalse(component.is_failed())
# Surely it can't be stopped when already dead
self.assertRaises(ValueError, component.stop)
# Nor started
......@@ -235,6 +238,7 @@ class ComponentTests(BossUtils, unittest.TestCase):
self.assertFalse(self.__stop_called)
self.assertTrue(self.__failed_called)
self.assertTrue(component.running())
self.assertFalse(component.is_failed())
# Check it can't be started again
self.assertRaises(ValueError, component.start)
......@@ -247,6 +251,7 @@ class ComponentTests(BossUtils, unittest.TestCase):
self.assertFalse(self.__stop_called)
self.assertTrue(self.__failed_called)
self.assertFalse(component.running())
self.assertTrue(component.is_failed())
def __do_start_stop(self, kind):
"""
......@@ -271,6 +276,7 @@ class ComponentTests(BossUtils, unittest.TestCase):
self.assertTrue(self.__stop_called)
self.assertFalse(self.__failed_called)
self.assertFalse(component.running())
self.assertFalse(component.is_failed())
# Check it can't be stopped twice
self.assertRaises(ValueError, component.stop)
# Or failed
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment