[Buildbot-devel] [PATCH 4/4] Support concurrency limits at the level of a BuildSlave

Dustin J. Mitchell dustin at zmanda.com
Fri Jun 22 18:06:09 UTC 2007


2007-06-22  Dustin J. Mitchell <dustin at zmanda.com>
    * buildbot/buildslave.py buildbot/process/builder.py: Add a concurrency
      limit to the BuildSlave class, and use that to limit the total
      number of concurrent builds on a given BuildSlave.
    * buildbot/scripts/sample.cfg: describe new concurrency_limit keyword arg
    * buildbot/process/builder.py: call the botmaster's maybeStartAllBuilds
      when a build is finished, to potentially trigger a build from another
      builder.
    * docs/buildbot.texinfo: documentation

Index: wip/buildbot/buildslave.py
===================================================================
--- wip.orig/buildbot/buildslave.py	2007-06-22 12:39:43.384628488 -0500
+++ wip/buildbot/buildslave.py	2007-06-22 12:45:58.480588142 -0500
@@ -9,10 +9,18 @@
     running builds.  I am instantiated by the configuration file, and can be
     subclassed to add extra functionality."""
 
-    def __init__(self, name, password):
+    def __init__(self, name, password, concurrency_limit=None):
+        """
+        @param name: botname this machine will supply when it connects
+        @param password: password this machine will supply when
+            it connects
+        @param concurrency_limit: maximum number of simultaneous builds
+            (default: None for no limit)
+        """
         BotPerspective.__init__(self, name)
         self.password = password
         self.slavebuilders = []
+        self.concurrency_limit = concurrency_limit
 
     def consumeTheSoulOfYourSuccessor(self, new):
         """
@@ -20,8 +28,9 @@
         BuildSlave objects are remotely referenced, we can't replace them
         without disconnecting the slave, yet there's no reason to do that.
         """
-        BotPerspective.consumeTheSoulOfYourSuccessor(new)
+        BotPerspective.consumeTheSoulOfYourSuccessor(self, new)
         self.password = new.password
+        self.concurrency_limit = new.concurrency_limit
 
     def __repr__(self):
         builders = self.botmaster.getBuildersForSlave(self.slavename)
@@ -44,4 +53,11 @@
         can start a build.  This function can be used to limit overall
         concurrency on the buildslave.
         """
+        if self.concurrency_limit:
+            num_active_builders = len([
+                sb for sb in self.slavebuilders
+                if sb.isBusy()])
+            if num_active_builders >= self.concurrency_limit:
+                return False
+
         return True
Index: wip/buildbot/process/builder.py
===================================================================
--- wip.orig/buildbot/process/builder.py	2007-06-22 12:39:43.388628361 -0500
+++ wip/buildbot/process/builder.py	2007-06-22 12:39:47.312503723 -0500
@@ -39,7 +39,7 @@
 
     def canStartBuild(self):
         # if this SlaveBuilder is busy, then it's definitely not available
-        if self.state != IDLE:
+        if self.isBusy():
             return False
 
         # otherwise, check in with the BuildSlave
@@ -49,6 +49,9 @@
         # no slave? not very available.
         return False
 
+    def isBusy(self):
+        return self.state in (PINGING, BUILDING)
+
     def attached(self, slave, remote, commands):
         """
         @type  slave: L{buildbot.buildslave.BuildSlave}
@@ -100,7 +103,7 @@
 
     def buildFinished(self):
         self.state = IDLE
-        reactor.callLater(0, self.builder.maybeStartBuild)
+        reactor.callLater(0, self.builder.botmaster.maybeStartAllBuilds)
 
     def ping(self, timeout, status=None):
         """Ping the slave to make sure it is still there. Returns a Deferred
Index: wip/buildbot/scripts/sample.cfg
===================================================================
--- wip.orig/buildbot/scripts/sample.cfg	2007-06-22 12:30:27.762215128 -0500
+++ wip/buildbot/scripts/sample.cfg	2007-06-22 12:39:47.316503596 -0500
@@ -26,6 +26,10 @@
     BuildSlave("bot1name", "bot1passwd")
 )
 
+# to limit to two concurrent builds on a slave, use
+#  c['bots'].append(
+#      BuildSlave("bot1name", "bot1passwd", concurrency_limit=2)
+#  )
 
 # 'slavePortnum' defines the TCP port to listen on. This must match the value
 # configured into the buildslaves (with their --master option)
Index: wip/docs/buildbot.texinfo
===================================================================
--- wip.orig/docs/buildbot.texinfo	2007-06-22 12:30:27.762215128 -0500
+++ wip/docs/buildbot.texinfo	2007-06-22 12:39:47.316503596 -0500
@@ -2235,6 +2235,18 @@
 will be rejected when they attempt to connect, and a message
 describing the problem will be put in the log file (see @ref{Logfiles}).
 
+The @code{BuildSlave} constructor can take an optional
+ at code{concurrency_limit} parameter to limit the number of builds that
+it will execute simultaneously:
+
+ at example
+from buildbot.buildslave import BuildSlave
+c['bots'] = []
+c['bots'].append(BuildSlave("bot-linux", "linuxpassword", concurrency_limit=2))
+ at end example
+
+The @code{BuildSlave} class can be subclassed to implement more
+sophisticated functionality at the level of a single buildslave.
 
 @node Defining Builders, Defining Status Targets, Buildslave Specifiers, Configuration
 @section Defining Builders

-- 
        Dustin J. Mitchell
        Storage Software Engineer, Zmanda, Inc.
        http://www.zmanda.com/




More information about the devel mailing list