[Buildbot-commits] buildbot/buildbot master.py,1.85,1.86

Brian Warner warner at users.sourceforge.net
Tue Nov 15 08:57:01 UTC 2005


Update of /cvsroot/buildbot/buildbot/buildbot
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv17588/buildbot

Modified Files:
	master.py 
Log Message:
Revision: arch at buildbot.sf.net--2004/buildbot--dev--0--patch-424
Creator:  Brian Warner <warner at lothar.com>

serialize config-file loading

	* buildbot/master.py (BuildMaster.loadConfig): serialize the
	config-file loading, specifically to make sure old StatusTargets
	are finished shutting down before new ones start up (thus
	resolving a bug in which changing the Waterfall object would fail
	because both new and old instances were claiming the same
	listening port). Also load new Schedulers after all the new
	Builders are set up, in case they fire off a new build right away.
	* buildbot/test/test_config.py (StartService): test it


Index: master.py
===================================================================
RCS file: /cvsroot/buildbot/buildbot/buildbot/master.py,v
retrieving revision 1.85
retrieving revision 1.86
diff -u -d -r1.85 -r1.86
--- master.py	5 Nov 2005 22:52:59 -0000	1.85
+++ master.py	15 Nov 2005 08:56:58 -0000	1.86
@@ -802,9 +802,10 @@
 
         # now we're committed to implementing the new configuration, so do
         # it atomically
+        # TODO: actually, this is spread across a couple of Deferreds, so it
+        # really isn't atomic.
 
-        # asynchronous updates can add a Deferred to this list
-        dl = []
+        d = defer.succeed(None)
 
         self.projectName = projectName
         self.projectURL = projectURL
@@ -813,7 +814,7 @@
         # self.bots: Disconnect any that were attached and removed from the
         # list. Update self.checker with the new list of passwords,
         # including debug/change/status.
-        dl.append(self.loadConfig_Slaves(bots))
+        d.addCallback(lambda res: self.loadConfig_Slaves(bots))
 
         # self.debugPassword
         if debugPassword:
@@ -825,28 +826,27 @@
             # changing
             if self.manhole:
                 # disownServiceParent may return a Deferred
-                d = defer.maybeDeferred(self.manhole.disownServiceParent)
-                dl.append(d)
+                d.addCallback(lambda res: self.manhole.disownServiceParent())
                 self.manhole = None
             if manhole:
                 self.manhole = manhole
                 manhole.setServiceParent(self)
 
-        dl.append(self.loadConfig_Sources(sources))
-        dl.append(self.loadConfig_Schedulers(schedulers))
-
         # add/remove self.botmaster.builders to match builders. The
         # botmaster will handle startup/shutdown issues.
-        dl.append(self.loadConfig_Builders(builders))
+        d.addCallback(lambda res: self.loadConfig_Builders(builders))
 
-        d = self.loadConfig_status(status)
-        dl.append(d)
+        d.addCallback(lambda res: self.loadConfig_status(status))
+
+        # Schedulers are added after Builders in case they start right away
+        d.addCallback(lambda res: self.loadConfig_Schedulers(schedulers))
+        # and Sources go after Schedulers for the same reason
+        d.addCallback(lambda res: self.loadConfig_Sources(sources))
 
         # self.slavePort
         if self.slavePortnum != slavePortnum:
             if self.slavePort:
-                d = defer.maybeDeferred(self.slavePort.disownServiceParent)
-                dl.append(d)
+                d.addCallback(lambda res: self.slavePort.disownServiceParent())
                 self.slavePort = None
             if slavePortnum is not None:
                 self.slavePort = internet.TCPServer(slavePortnum,
@@ -855,9 +855,11 @@
                 log.msg("BuildMaster listening on port %d" % slavePortnum)
             self.slavePortnum = slavePortnum
         
-        log.msg("configuration updated")
-        self.readConfig = True
-        return defer.DeferredList(dl, fireOnOneErrback=1, consumeErrors=1)
+        log.msg("configuration update started")
+        d.addCallback(lambda res: log.msg("configuration update complete"))
+        self.readConfig = True # TODO: consider not setting this until the
+                               # Deferred fires.
+        return d
 
     def loadConfig_Slaves(self, bots):
         # set up the Checker with the names and passwords of all valid bots
@@ -877,7 +879,7 @@
 
         # all done
         self.bots = bots
-        return defer.DeferredList(dl, fireOnOneErrback=1, consumeErrors=1)
+        return defer.DeferredList(dl, fireOnOneErrback=1, consumeErrors=0)
 
     def loadConfig_Sources(self, sources):
         log.msg("loadConfig_Sources, change_svc is", self.change_svc,
@@ -888,16 +890,19 @@
               for source in oldsources if source not in sources]
         [self.change_svc.addSource(source)
          for source in sources if source not in self.change_svc]
-        return defer.DeferredList(dl, fireOnOneErrback=1, consumeErrors=1)
+        return defer.DeferredList(dl, fireOnOneErrback=1, consumeErrors=0)
 
     def loadConfig_Schedulers(self, newschedulers):
         old = [s for s in self.schedulers if s not in newschedulers]
         [self.schedulers.remove(s) for s in old]
         dl = [defer.maybeDeferred(s.disownServiceParent) for s in old]
-        [s.setServiceParent(self)
-         for s in newschedulers if s not in self.schedulers]
-        self.schedulers = newschedulers
-        return defer.DeferredList(dl, fireOnOneErrback=1, consumeErrors=1)
+        def addNewOnes(res):
+            [s.setServiceParent(self)
+             for s in newschedulers if s not in self.schedulers]
+            self.schedulers = newschedulers
+        d = defer.DeferredList(dl, fireOnOneErrback=1)
+        d.addCallback(addNewOnes)
+        return d
 
     def loadConfig_Builders(self, newBuilders):
         dl = []
@@ -959,7 +964,7 @@
         # now that everything is up-to-date, make sure the names are in the
         # desired order
         self.botmaster.builderNames = newNames
-        return defer.DeferredList(dl, fireOnOneErrback=1, consumeErrors=1)
+        return defer.DeferredList(dl, fireOnOneErrback=1, consumeErrors=0)
 
     def loadConfig_status(self, status):
         dl = []
@@ -971,14 +976,16 @@
                 d = defer.maybeDeferred(s.disownServiceParent)
                 dl.append(d)
                 self.statusTargets.remove(s)
-        # add new ones
-        for s in status:
-            if not s in self.statusTargets:
-                log.msg("adding IStatusReceiver", s)
-                s.setServiceParent(self)
-                self.statusTargets.append(s)
-
-        return defer.DeferredList(dl, fireOnOneErrback=1, consumeErrors=1)
+        # after those are finished going away, add new ones
+        def addNewOnes(res):
+            for s in status:
+                if not s in self.statusTargets:
+                    log.msg("adding IStatusReceiver", s)
+                    s.setServiceParent(self)
+                    self.statusTargets.append(s)
+        d = defer.DeferredList(dl, fireOnOneErrback=1)
+        d.addCallback(addNewOnes)
+        return d
 
 
     def addChange(self, change):





More information about the Commits mailing list