soc-2008-mxcurioni: merged changes to revision 23516
[blender.git] / release / scripts / io / netrender / balancing.py
1 import time
2
3 from netrender.utils import *
4 import netrender.model
5
6 class RatingRule:
7         def rate(self, job):
8                 return 0
9
10 class ExclusionRule:
11         def test(self, job):
12                 return False
13
14 class PriorityRule:
15         def test(self, job):
16                 return False
17
18 class Balancer:
19         def __init__(self):
20                 self.rules = []
21                 self.priorities = []
22                 self.exceptions = []
23         
24         def addRule(self, rule):
25                 self.rules.append(rule)
26         
27         def addPriority(self, priority):
28                 self.priorities.append(priority)
29                 
30         def addException(self, exception):
31                 self.exceptions.append(exception)
32         
33         def applyRules(self, job):
34                 return sum((rule.rate(job) for rule in self.rules))
35         
36         def applyPriorities(self, job):
37                 for priority in self.priorities:
38                         if priority.test(job):
39                                 return True # priorities are first
40                 
41                 return False
42         
43         def applyExceptions(self, job):
44                 for exception in self.exceptions:
45                         if exception.test(job):
46                                 return True # exceptions are last
47                         
48                 return False
49         
50         def sortKey(self, job):
51                 return (1 if self.applyExceptions(job) else 0, # exceptions after
52                                                 0 if self.applyPriorities(job) else 1, # priorities first
53                                                 self.applyRules(job))
54         
55         def balance(self, jobs):
56                 if jobs:
57                         jobs.sort(key=self.sortKey)
58                         return jobs[0]
59                 else:
60                         return None
61         
62 # ==========================
63
64 class RatingUsage(RatingRule):
65         def rate(self, job):
66                 # less usage is better
67                 return job.usage / job.priority
68
69 class NewJobPriority(PriorityRule):
70         def __init__(self, limit = 1):
71                 self.limit = limit
72                 
73         def test(self, job):
74                 return job.countFrames(status = DONE) < self.limit
75
76 class MinimumTimeBetweenDispatchPriority(PriorityRule):
77         def __init__(self, limit = 10):
78                 self.limit = limit
79                 
80         def test(self, job):
81                 return job.countFrames(status = DISPATCHED) == 0 and (time.time() - job.last_dispatched) / 60 > self.limit
82
83 class ExcludeQueuedEmptyJob(ExclusionRule):
84         def test(self, job):
85                 return job.status != JOB_QUEUED or job.countFrames(status = QUEUED) == 0
86         
87 class ExcludeSlavesLimit(ExclusionRule):
88         def __init__(self, count_jobs, count_slaves, limit = 0.75):
89                 self.count_jobs = count_jobs
90                 self.count_slaves = count_slaves
91                 self.limit = limit
92                 
93         def test(self, job):
94                 return not ( self.count_jobs() == 1 or self.count_slaves() <= 1 or float(job.countSlaves() + 1) / self.count_slaves() <= self.limit )