1 # ##### BEGIN GPL LICENSE BLOCK #####
3 # This program is free software; you can redistribute it and/or
4 # modify it under the terms of the GNU General Public License
5 # as published by the Free Software Foundation; either version 2
6 # of the License, or (at your option) any later version.
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # GNU General Public License for more details.
13 # You should have received a copy of the GNU General Public License
14 # along with this program; if not, write to the Free Software Foundation,
15 # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 # ##### END GPL LICENSE BLOCK #####
21 from netrender
.utils
import *
22 import netrender
.model
61 def ruleByID(self
, rule_id
):
62 for rule
in self
.rules
:
63 if rule
.id() == rule_id
:
65 for rule
in self
.priorities
:
66 if rule
.id() == rule_id
:
68 for rule
in self
.exceptions
:
69 if rule
.id() == rule_id
:
74 def addRule(self
, rule
):
75 self
.rules
.append(rule
)
77 def addPriority(self
, priority
):
78 self
.priorities
.append(priority
)
80 def addException(self
, exception
):
81 self
.exceptions
.append(exception
)
83 def applyRules(self
, job
):
84 return sum((rule
.rate(job
) for rule
in self
.rules
if rule
.enabled
))
86 def applyPriorities(self
, job
):
87 for priority
in self
.priorities
:
88 if priority
.enabled
and priority
.test(job
):
89 return True # priorities are first
93 def applyExceptions(self
, job
):
94 for exception
in self
.exceptions
:
95 if exception
.enabled
and exception
.test(job
):
96 return True # exceptions are last
100 def sortKey(self
, job
):
101 return (1 if self
.applyExceptions(job
) else 0, # exceptions after
102 0 if self
.applyPriorities(job
) else 1, # priorities first
103 self
.applyRules(job
))
105 def balance(self
, jobs
):
107 # use inline copy to make sure the list is still accessible while sorting
108 jobs
[:] = sorted(jobs
, key
=self
.sortKey
)
113 # ==========================
115 class RatingUsage(RatingRule
):
117 return "Usage per job"
120 # less usage is better
121 return job
.usage
/ job
.priority
123 return { "type": "rating",
124 "enabled": self
.enabled
,
125 "descritpiton":str(self
),
131 class RatingUsageByCategory(RatingRule
):
132 def __init__(self
, get_jobs
):
134 self
.getJobs
= get_jobs
137 return "Usage per category"
140 total_category_usage
= sum([j
.usage
for j
in self
.getJobs() if j
.category
== job
.category
])
141 maximum_priority
= max([j
.priority
for j
in self
.getJobs() if j
.category
== job
.category
])
143 # less usage is better
144 return total_category_usage
/ maximum_priority
147 return { "type": "rating",
148 "enabled": self
.enabled
,
149 "editable": self
.editable
,
150 "descritpiton":str(self
),
156 class NewJobPriority(PriorityRule
):
157 def __init__(self
, limit
= 1):
161 def setLimit(self
, value
):
162 self
.limit
= int(value
)
165 return "less than %i frame%s done" % (self
.limit
, "s" if self
.limit
> 1 else "")
168 return "Priority to new jobs"
171 return job
.countFrames(status
= netrender
.model
.FRAME_DONE
) < self
.limit
173 return { "type": "priority",
174 "enabled": self
.enabled
,
175 "editable": self
.editable
,
176 "descritpiton":str(self
),
178 "limit_str":self
.str_limit(),
182 class MinimumTimeBetweenDispatchPriority(PriorityRule
):
183 def __init__(self
, limit
= 10):
187 def setLimit(self
, value
):
188 self
.limit
= int(value
)
191 return "more than %i minute%s since last" % (self
.limit
, "s" if self
.limit
> 1 else "")
194 return "Priority to jobs that haven't been dispatched recently"
197 return job
.countFrames(status
= netrender
.model
.FRAME_DISPATCHED
) == 0 and (time
.time() - job
.last_dispatched
) / 60 > self
.limit
200 return { "type": "priority",
201 "enabled": self
.enabled
,
202 "editable": self
.editable
,
203 "descritpiton":str(self
),
205 "limit_str":self
.str_limit(),
209 class ExcludeQueuedEmptyJob(ExclusionRule
):
214 return "Exclude non queued or empty jobs"
217 return job
.status
!= netrender
.model
.JOB_QUEUED
or job
.countFrames(status
= netrender
.model
.FRAME_QUEUED
) == 0
220 return { "type": "exception",
221 "enabled": self
.enabled
,
222 "editable": self
.editable
,
223 "descritpiton":str(self
),
230 class ExcludeSlavesLimit(ExclusionRule
):
231 def __init__(self
, count_jobs
, count_slaves
, limit
= 0.75):
233 self
.count_jobs
= count_jobs
234 self
.count_slaves
= count_slaves
237 def setLimit(self
, value
):
238 self
.limit
= float(value
)
241 return "more than %.0f%% of all slaves" % (self
.limit
* 100)
244 return "Exclude jobs that would use too many slaves"
247 return not ( self
.count_jobs() == 1 or self
.count_slaves() <= 1 or float(job
.countSlaves() + 1) / self
.count_slaves() <= self
.limit
)
250 return { "type": "exception",
251 "enabled": self
.enabled
,
252 "editable": self
.editable
,
253 "descritpiton":str(self
),
255 "limit_str":self
.str_limit(),