netrender: more load balancing rules
authorMartin Poirier <theeth@yahoo.com>
Mon, 21 Sep 2009 16:01:31 +0000 (16:01 +0000)
committerMartin Poirier <theeth@yahoo.com>
Mon, 21 Sep 2009 16:01:31 +0000 (16:01 +0000)
release/io/netrender/balancing.py
release/io/netrender/master.py
release/io/netrender/model.py

index 89e1e3f7b069b94ee52e867954b237319d33fb20..62b6dcee519633bb059727d2b10dcd86d5ca3eb9 100644 (file)
@@ -64,12 +64,31 @@ class Balancer:
 
 class RatingCredit(RatingRule):
        def rate(self, job):
-               return -job.credits # more credit is better (sort at first in list)
+               return -job.credits * job.priority # more credit is better (sort at first in list)
 
 class NewJobPriority(PriorityRule):
+       def __init__(self, limit = 1):
+               self.limit = limit
+               
+       def test(self, job):
+               return job.countFrames(status = DISPATCHED) < self.limit
+
+class MinimumTimeBetweenDispatchPriority(PriorityRule):
+       def __init__(self, limit = 10):
+               self.limit = limit
+               
        def test(self, job):
-               return job.countFrames(status = DISPATCHED) == 0
+               return (time.time() - job.last_dispatched) / 60 > self.limit
 
 class ExcludeQueuedEmptyJob(ExclusionRule):
        def test(self, job):
                return job.status != JOB_QUEUED or job.countFrames(status = QUEUED) == 0
+       
+class ExcludeSlavesLimit(ExclusionRule):
+       def __init__(self, count_jobs, count_slaves, limit = 0.75):
+               self.count_jobs = count_jobs
+               self.count_slaves = count_slaves
+               self.limit = limit
+               
+       def test(self, job):
+               return not ( self.count_jobs() == 1 or float(job.countSlaves() + 1) / self.count_slaves() <= self.limit )
\ No newline at end of file
index 58c6c1b2d006c957ae2b8ddabaa0d2b7feba943c..1bff5f6340b4e1ca6fc19c52c649bf25850db774 100644 (file)
@@ -575,7 +575,9 @@ class RenderMasterServer(http.server.HTTPServer):
                self.balancer = netrender.balancing.Balancer()
                self.balancer.addRule(netrender.balancing.RatingCredit())
                self.balancer.addException(netrender.balancing.ExcludeQueuedEmptyJob())
+               self.balancer.addException(netrender.balancing.ExcludeSlavesLimit(self.countJobs, self.countSlaves))
                self.balancer.addPriority(netrender.balancing.NewJobPriority())
+               self.balancer.addPriority(netrender.balancing.MinimumTimeBetweenDispatchPriority())
                
                if not os.path.exists(self.path):
                        os.mkdir(self.path)
@@ -607,7 +609,18 @@ class RenderMasterServer(http.server.HTTPServer):
        
        def update(self):
                self.balancer.balance(self.jobs)
+       
+       def countJobs(self, status = JOB_QUEUED):
+               total = 0
+               for j in self.jobs:
+                       if j.status == status:
+                               total += 1
                
+               return total
+       
+       def countSlaves(self):
+               return len(self.slaves)
+       
        def removeJob(self, id):
                job = self.jobs_map.pop(id)
 
index 9a6645e79cfe39e04c71f2b62b9a883dba21d4e7..e8046d7ac8c5ab4cadeb78ab6e46a6b8a46ad134 100644 (file)
@@ -97,15 +97,14 @@ class RenderJob:
        
        def countFrames(self, status=QUEUED):
                total = 0
-               for j in self.frames:
-                       if j.status == status:
+               for f in self.frames:
+                       if f.status == status:
                                total += 1
                
                return total
        
        def countSlaves(self):
                return len(set((frame.slave for frame in self.frames if frame.status == DISPATCHED)))
-               
        
        def framesStatus(self):
                results = {