Module: deluge
Branch: master
Commit: 7be5b4c8bc5a1c187edb42015c1c3ce8b8dafaaf

Author: Andrew Resch <[email protected]>
Date:   Sat Mar 27 20:05:20 2010 -0700

Add 2 new states to Component: Starting and Stopping
Fix issue where a Component could have it's start and stop methods called more 
than once while waiting for their deferreds to fire

---

 deluge/component.py     |   32 +++++++++++++++++++++++++-------
 tests/test_component.py |   15 +++++++++++++++
 2 files changed, 40 insertions(+), 7 deletions(-)

diff --git a/deluge/component.py b/deluge/component.py
index cdeaa59..9ca34a1 100644
--- a/deluge/component.py
+++ b/deluge/component.py
@@ -68,17 +68,23 @@ class Component(object):
                      call to stop() will be issued prior to shutdown().
 
     **States:**
-    
-        A Component can be in one of these 3 states.
-        
+
+        A Component can be in one of these 5 states.
+
         **Started** - The Component has been started by the 
:class:`ComponentRegistry`
                     and will have it's update timer started.
-        
+
+        **Starting** - The Component has had it's start method called, but it 
hasn't
+                    fully started yet.
+
         **Stopped** - The Component has either been stopped or has yet to be 
started.
-        
+
+        **Stopping** - The Component has had it's stop method called, but it 
hasn't
+                    fully stopped yet.
+
         **Paused** - The Component has had it's update timer stopped, but will
                     still be considered in a Started state.
-                    
+
     """
     def __init__(self, name, interval=1, depend=None):
         self._component_name = name
@@ -86,6 +92,8 @@ class Component(object):
         self._component_depend = depend
         self._component_state = "Stopped"
         self._component_timer = None
+        self._component_starting_deferred = None
+        self._component_stopping_deferred = None
         _ComponentRegistry.register(self)
 
     def _component_start_timer(self):
@@ -96,15 +104,20 @@ class Component(object):
     def _component_start(self):
         def on_start(result):
             self._component_state = "Started"
+            self._component_starting_deferred = None
             self._component_start_timer()
             return True
 
         if self._component_state == "Stopped":
             if hasattr(self, "start"):
+                self._component_state = "Starting"
                 d = maybeDeferred(self.start)
                 d.addCallback(on_start)
+                self._component_starting_deferred = d
             else:
                 d = maybeDeferred(on_start, None)
+        elif self._component_state == "Starting":
+            return self._component_starting_deferred
         elif self._component_state == "Started":
             d = succeed(True)
         else:
@@ -119,13 +132,18 @@ class Component(object):
                 self._component_timer.stop()
             return True
 
-        if self._component_state != "Stopped":
+        if self._component_state != "Stopped" and self._component_state != 
"Stopping":
             if hasattr(self, "stop"):
+                self._component_state = "Stopping"
                 d = maybeDeferred(self.stop)
                 d.addCallback(on_stop)
+                self._component_stopping_deferred = d
             else:
                 d = maybeDeferred(on_stop, None)
 
+        if self._component_state == "Stopping":
+            return self._component_stopping_deferred
+
         return succeed(None)
 
     def _component_pause(self):
diff --git a/tests/test_component.py b/tests/test_component.py
index 81022a3..f3a1e17 100644
--- a/tests/test_component.py
+++ b/tests/test_component.py
@@ -6,10 +6,14 @@ class testcomponent(component.Component):
     def __init__(self, name):
         component.Component.__init__(self, name)
         self.start_count = 0
+        self.stop_count = 0
 
     def start(self):
         self.start_count += 1
 
+    def stop(self):
+        self.stop_count += 1
+
 class testcomponent_delaystart(testcomponent):
     def start(self):
         def do_sleep():
@@ -25,18 +29,26 @@ class testcomponent_update(component.Component):
         component.Component.__init__(self, name)
         self.counter = 0
         self.start_count = 0
+        self.stop_count = 0
 
     def update(self):
         self.counter += 1
 
+    def stop(self):
+        self.stop_count += 1
+
 class testcomponent_shutdown(component.Component):
     def __init__(self, name):
         component.Component.__init__(self, name)
         self.shutdowned = False
+        self.stop_count = 0
 
     def shutdown(self):
         self.shutdowned = True
 
+    def stop(self):
+        self.stop_count += 1
+
 class ComponentTestClass(unittest.TestCase):
     def tearDown(self):
         component._ComponentRegistry.components = {}
@@ -106,6 +118,7 @@ class ComponentTestClass(unittest.TestCase):
         def on_stop(result, c):
             self.assertEquals(c._component_state, "Stopped")
             self.assertFalse(c._component_timer.running)
+            self.assertEquals(c.stop_count, 1)
 
         def on_start(result, c):
             self.assertEquals(c._component_state, "Started")
@@ -120,6 +133,7 @@ class ComponentTestClass(unittest.TestCase):
         def on_stop(*args):
             for c in args[1:]:
                 self.assertEquals(c._component_state, "Stopped")
+                self.assertEquals(c.stop_count, 1)
 
         def on_start(*args):
             for c in args[1:]:
@@ -169,6 +183,7 @@ class ComponentTestClass(unittest.TestCase):
         def on_shutdown(result, c1):
             self.assertTrue(c1.shutdowned)
             self.assertEquals(c1._component_state, "Stopped")
+            self.assertEquals(c1.stop_count, 1)
 
         def on_start(result, c1):
             d = component.shutdown()

-- 
You received this message because you are subscribed to the Google Groups 
"deluge-commit" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/deluge-commit?hl=en.

Reply via email to