[Buildbot-commits] buildbot/buildbot/status client.py,1.21,1.22

Brian Warner warner at users.sourceforge.net
Thu Aug 18 08:30:04 UTC 2005


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

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

make 'try' status reporting actually work

	* buildbot/scripts/tryclient.py (Try): make 'try' status reporting
	actually work. It's functional but still kind of clunky. Also, it
	only works with the pb-style.. needs to be made to work with the
	jobdir-style too.

	* buildbot/status/client.py (RemoteBuildSet): new class
	(RemoteBuildRequest): same
	(RemoteBuild.remote_waitUntilFinished): return the RemoteBuild
	object, not the internal BuildStatus object.
	(RemoteBuild.remote_subscribe): new method to subscribe to builds
	outside of the usual buildStarted() return value.
	(BuildSubscriber): support class for RemoteBuild.remote_subscribe

	* buildbot/scheduler.py (Try_Jobdir): convey buildsetID properly
	(Try_Userpass_Perspective.perspective_try): return a remotely
	usable BuildSetStatus object

	* buildbot/interfaces.py (IBuildStatus): remove obsolete
	isStarted()/waitUntilStarted()

--This line, and those below, will be ignored--
Files to commit:
   <can't compute list>

This list might be incomplete or outdated if editing the log
message was not invoked from an up-to-date changes buffer!


Index: client.py
===================================================================
RCS file: /cvsroot/buildbot/buildbot/buildbot/status/client.py,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -d -r1.21 -r1.22
--- client.py	17 Aug 2005 02:15:37 -0000	1.21
+++ client.py	18 Aug 2005 08:30:00 -0000	1.22
@@ -22,6 +22,48 @@
         return None
     return IRemote(obj)
 
+
+class RemoteBuildSet(pb.Referenceable):
+    def __init__(self, buildset):
+        self.b = buildset
+
+    def remote_getSourceStamp(self):
+        return self.b.getSourceStamp()
+
+    def remote_getReason(self):
+        return self.b.getReason()
+
+    def remote_getID(self):
+        return self.b.getID()
+
+    def remote_getBuilderNames(self):
+        return self.b.getBuilderNames()
+
+    def remote_getBuildRequests(self):
+        """Returns a list of (builderName, BuildRequest) tuples."""
+        return [(br.getBuilderName(), IRemote(br))
+                for br in self.b.getBuildRequests()]
+
+    def remote_isFinished(self):
+        return self.b.isFinished()
+
+    def remote_waitUntilSuccess(self):
+        d = self.b.waitUntilSuccess()
+        d.addCallback(lambda res: self)
+        return d
+
+    def remote_waitUntilFinished(self):
+        d = self.b.waitUntilFinished()
+        d.addCallback(lambda res: self)
+        return d
+
+    def remote_getResults(self):
+        return self.b.getResults()
+
+components.registerAdapter(RemoteBuildSet,
+                           interfaces.IBuildSetStatus, IRemote)    
+
+
 class RemoteBuilder(pb.Referenceable):
     def __init__(self, builder):
         self.b = builder
@@ -51,9 +93,46 @@
 components.registerAdapter(RemoteBuilder,
                            interfaces.IBuilderStatus, IRemote)    
 
+
+class RemoteBuildRequest(pb.Referenceable):
+    def __init__(self, buildreq):
+        self.b = buildreq
+        self.observers = []
+
+    def remote_getSourceStamp(self):
+        return self.b.getSourceStamp()
+
+    def remote_getBuilderName(self):
+        return self.b.getBuilderName()
+
+    def remote_subscribe(self, observer):
+        """The observer's remote_newbuild method will be called (with two
+        arguments: the RemoteBuild object, and our builderName) for each new
+        Build that is created to handle this BuildRequest."""
+        self.observers.append(observer)
+        def send(bs):
+            d = observer.callRemote("newbuild",
+                                    IRemote(bs), self.b.getBuilderName())
+            d.addErrback(lambda err: None)
+        reactor.callLater(0, self.b.subscribe, send)
+
+    def remote_unsubscribe(self, observer):
+        # PB (well, at least oldpb) doesn't re-use RemoteReference instances,
+        # so sending the same object across the wire twice will result in two
+        # separate objects that compare as equal ('a is not b' and 'a == b').
+        # That means we can't use a simple 'self.observers.remove(observer)'
+        # here.
+        for o in self.observers:
+            if o == observer:
+                self.observers.remove(o)
+
+components.registerAdapter(RemoteBuildRequest,
+                           interfaces.IBuildRequestStatus, IRemote)    
+
 class RemoteBuild(pb.Referenceable):
     def __init__(self, build):
         self.b = build
+        self.observers = []
 
     def remote_getBuilderName(self):
         return self.b.getBuilder().getName()
@@ -82,7 +161,9 @@
     def remote_waitUntilFinished(self):
         # the Deferred returned by callRemote() will fire when this build is
         # finished
-        return self.b.waitUntilFinished()
+        d = self.b.waitUntilFinished()
+        d.addCallback(lambda res: self)
+        return d
 
     def remote_getETA(self):
         return self.b.getETA()
@@ -96,15 +177,60 @@
     def remote_getColor(self):
         return self.b.getColor()
 
+    def remote_getResults(self):
+        return self.b.getResults()
+
     def remote_getLogs(self):
         logs = {}
         for name,log in self.b.getLogs().items():
             logs[name] = IRemote(log)
         return logs
 
+    def remote_subscribe(self, observer, updateInterval=None):
+        """The observer will have remote_stepStarted(buildername, build,
+        stepname, step), remote_stepFinished(buildername, build, stepname,
+        step, results), and maybe remote_buildETAUpdate(buildername, build,
+        eta)) messages sent to it."""
+        self.observers.append(observer)
+        s = BuildSubscriber(observer)
+        self.b.subscribe(s, updateInterval)
+
+    def remote_unsubscribe(self, observer):
+        # TODO: is the observer automatically unsubscribed when the build
+        # finishes? Or are they responsible for unsubscribing themselves
+        # anyway? How do we avoid a race condition here?
+        for o in self.observers:
+            if o == observer:
+                self.observers.remove(o)
+
+
 components.registerAdapter(RemoteBuild,
                            interfaces.IBuildStatus, IRemote)    
 
+class BuildSubscriber:
+    def __init__(self, observer):
+        self.observer = observer
+
+    def buildETAUpdate(self, build, eta):
+        self.observer.callRemote("buildETAUpdate",
+                                 build.getBuilder().getName(),
+                                 IRemote(build),
+                                 eta)
+
+    def stepStarted(self, build, step):
+        self.observer.callRemote("stepStarted",
+                                 build.getBuilder().getName(),
+                                 IRemote(build),
+                                 step.getName(), IRemote(step))
+        return None
+
+    def stepFinished(self, build, step, results):
+        self.observer.callRemote("stepFinished",
+                                 build.getBuilder().getName(),
+                                 IRemote(build),
+                                 step.getName(), IRemote(step),
+                                 results)
+
 
 class RemoteBuildStep(pb.Referenceable):
     def __init__(self, step):





More information about the Commits mailing list