diff options
author | Martin Poirier <theeth@yahoo.com> | 2009-12-31 22:11:46 +0300 |
---|---|---|
committer | Martin Poirier <theeth@yahoo.com> | 2009-12-31 22:11:46 +0300 |
commit | 7c4e51049250f69acc965834c7c64c972881d6ec (patch) | |
tree | 90acb675c99037736bd8ddf67a75f191539b6403 /release/scripts/io/netrender | |
parent | 09994fb444bccbccdd7399fe414b4d7a49c773c2 (diff) |
netrender: edit balancing rules limits and enable/disable them from the web interface
Diffstat (limited to 'release/scripts/io/netrender')
-rw-r--r-- | release/scripts/io/netrender/balancing.py | 72 | ||||
-rw-r--r-- | release/scripts/io/netrender/master.py | 23 | ||||
-rw-r--r-- | release/scripts/io/netrender/master_html.py | 103 | ||||
-rw-r--r-- | release/scripts/io/netrender/netrender.js | 13 |
4 files changed, 152 insertions, 59 deletions
diff --git a/release/scripts/io/netrender/balancing.py b/release/scripts/io/netrender/balancing.py index e09b19f956c..ebd54f6a8b9 100644 --- a/release/scripts/io/netrender/balancing.py +++ b/release/scripts/io/netrender/balancing.py @@ -22,14 +22,23 @@ from netrender.utils import * import netrender.model class RatingRule: + def __init__(self): + self.enabled = True + def rate(self, job): return 0 class ExclusionRule: + def __init__(self): + self.enabled = True + def test(self, job): return False class PriorityRule: + def __init__(self): + self.enabled = True + def test(self, job): return False @@ -39,6 +48,19 @@ class Balancer: self.priorities = [] self.exceptions = [] + def ruleByID(self, rule_id): + for rule in self.rules: + if id(rule) == rule_id: + return rule + for rule in self.priorities: + if id(rule) == rule_id: + return rule + for rule in self.exceptions: + if id(rule) == rule_id: + return rule + + return None + def addRule(self, rule): self.rules.append(rule) @@ -49,18 +71,18 @@ class Balancer: self.exceptions.append(exception) def applyRules(self, job): - return sum((rule.rate(job) for rule in self.rules)) + return sum((rule.rate(job) for rule in self.rules if rule.enabled)) def applyPriorities(self, job): for priority in self.priorities: - if priority.test(job): + if priority.enabled and priority.test(job): return True # priorities are first return False def applyExceptions(self, job): for exception in self.exceptions: - if exception.test(job): + if exception.enabled and exception.test(job): return True # exceptions are last return False @@ -82,18 +104,20 @@ class Balancer: class RatingUsage(RatingRule): def __str__(self): - return "Usage rating" + return "Usage per job" def rate(self, job): # less usage is better return job.usage / job.priority class RatingUsageByCategory(RatingRule): - def __str__(self): - return "Usage per category rating" - def __init__(self, get_jobs): + super().__init__() self.getJobs = get_jobs + + def __str__(self): + return "Usage per category" + def rate(self, job): total_category_usage = sum([j.usage for j in self.getJobs() if j.category == job.category]) maximum_priority = max([j.priority for j in self.getJobs() if j.category == job.category]) @@ -102,28 +126,36 @@ class RatingUsageByCategory(RatingRule): return total_category_usage / maximum_priority class NewJobPriority(PriorityRule): + def __init__(self, limit = 1): + super().__init__() + self.limit = limit + + def setLimit(self, value): + self.limit = int(value) + def str_limit(self): return "less than %i frame%s done" % (self.limit, "s" if self.limit > 1 else "") def __str__(self): return "Priority to new jobs" - def __init__(self, limit = 1): - self.limit = limit - def test(self, job): return job.countFrames(status = DONE) < self.limit class MinimumTimeBetweenDispatchPriority(PriorityRule): + def __init__(self, limit = 10): + super().__init__() + self.limit = limit + + def setLimit(self, value): + self.limit = int(value) + def str_limit(self): return "more than %i minute%s since last" % (self.limit, "s" if self.limit > 1 else "") def __str__(self): return "Priority to jobs that haven't been dispatched recently" - def __init__(self, limit = 10): - self.limit = limit - def test(self, job): return job.countFrames(status = DISPATCHED) == 0 and (time.time() - job.last_dispatched) / 60 > self.limit @@ -135,16 +167,20 @@ class ExcludeQueuedEmptyJob(ExclusionRule): return job.status != JOB_QUEUED or job.countFrames(status = QUEUED) == 0 class ExcludeSlavesLimit(ExclusionRule): + def __init__(self, count_jobs, count_slaves, limit = 0.75): + super().__init__() + self.count_jobs = count_jobs + self.count_slaves = count_slaves + self.limit = limit + + def setLimit(self, value): + self.limit = float(value) + def str_limit(self): return "more than %.0f%% of all slaves" % (self.limit * 100) def __str__(self): return "Exclude jobs that would use too many slaves" - 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 self.count_slaves() <= 1 or float(job.countSlaves() + 1) / self.count_slaves() <= self.limit ) diff --git a/release/scripts/io/netrender/master.py b/release/scripts/io/netrender/master.py index a33606d19a0..00be3cf9bc9 100644 --- a/release/scripts/io/netrender/master.py +++ b/release/scripts/io/netrender/master.py @@ -456,6 +456,29 @@ class RenderHandler(http.server.BaseHTTPRequestHandler): # invalid url self.send_head(http.client.NO_CONTENT) # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + elif self.path == "/balance_limit": + length = int(self.headers['content-length']) + info_map = eval(str(self.rfile.read(length), encoding='utf8')) + for rule_id, limit in info_map.items(): + try: + rule = self.server.balancer.ruleByID(rule_id) + if rule: + rule.setLimit(limit) + except: + pass # invalid type + + self.send_head() + # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + elif self.path == "/balance_enable": + length = int(self.headers['content-length']) + info_map = eval(str(self.rfile.read(length), encoding='utf8')) + for rule_id, enabled in info_map.items(): + rule = self.server.balancer.ruleByID(rule_id) + if rule: + rule.enabled = enabled + + self.send_head() + # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- elif self.path.startswith("/cancel"): match = cancel_pattern.match(self.path) diff --git a/release/scripts/io/netrender/master_html.py b/release/scripts/io/netrender/master_html.py index af4db43ae9d..5f3b8be3dfd 100644 --- a/release/scripts/io/netrender/master_html.py +++ b/release/scripts/io/netrender/master_html.py @@ -80,6 +80,9 @@ def get(handler): def endTable(): output("</table>") + + def checkbox(title, value, script=""): + return """<input type="checkbox" title="%s" %s %s>""" % (title, "checked" if value else "", ("onclick=\"%s\"" % script) if script else "") if handler.path == "/html/netrender.js": f = open(os.path.join(src_folder, "netrender.js"), 'rb') @@ -105,16 +108,34 @@ def get(handler): startTable(caption = "Rules", class_style = "rules") - headerTable("type", "description", "limit") + headerTable("type", "enabled", "description", "limit") for rule in handler.server.balancer.rules: - rowTable("rating", rule, rule.str_limit() if hasattr(rule, "limit") else " ") + rowTable( + "rating", + checkbox("", rule.enabled, "balance_enable('%i', '%s')" % (id(rule), str(not rule.enabled))), + rule, + rule.str_limit() + + """<button title="edit limit" onclick="balance_edit('%i', '%s');">edit</button>""" % (id(rule), str(rule.limit)) if hasattr(rule, "limit") else " " + ) for rule in handler.server.balancer.priorities: - rowTable("priority", rule, rule.str_limit() if hasattr(rule, "limit") else " ") + rowTable( + "priority", + checkbox("", rule.enabled, "balance_enable('%i', '%s')" % (id(rule), str(not rule.enabled))), + rule, + rule.str_limit() + + """<button title="edit limit" onclick="balance_edit('%i', '%s');">edit</button>""" % (id(rule), str(rule.limit)) if hasattr(rule, "limit") else " " + ) for rule in handler.server.balancer.exceptions: - rowTable("exception", rule, rule.str_limit() if hasattr(rule, "limit") else " ") + rowTable( + "exception", + checkbox("", rule.enabled, "balance_enable('%i', '%s')" % (id(rule), str(not rule.enabled))), + rule, + rule.str_limit() + + """<button title="edit limit" onclick="balance_edit('%i', '%s');">edit</button>""" % (id(rule), str(rule.limit)) if hasattr(rule, "limit") else " " + ) endTable() @@ -132,49 +153,49 @@ def get(handler): startTable() headerTable( - " ", - "id", - "name", - "category", - "chunks", - "priority", - "usage", - "wait", - "status", - "length", - "done", - "dispatched", - "error", - "first", - "exception" - ) + " ", + "id", + "name", + "category", + "chunks", + "priority", + "usage", + "wait", + "status", + "length", + "done", + "dispatched", + "error", + "first", + "exception" + ) handler.server.balance() for job in handler.server.jobs: results = job.framesStatus() rowTable( - """<button title="cancel job" onclick="request('/cancel_%s', null);">X</button>""" % job.id + - """<button title="reset all frames" onclick="request('/resetall_%s_0', null);">R</button>""" % job.id, - job.id, - link(job.name, "/html/job" + job.id), - job.category if job.category else "<i>None</i>", - str(job.chunks) + - """<button title="increase priority" onclick="request('/edit_%s', "{'chunks': %i}");">+</button>""" % (job.id, job.chunks + 1) + - """<button title="decrease priority" onclick="request('/edit_%s', "{'chunks': %i}");" %s>-</button>""" % (job.id, job.chunks - 1, "disabled=True" if job.chunks == 1 else ""), - str(job.priority) + - """<button title="increase chunks size" onclick="request('/edit_%s', "{'priority': %i}");">+</button>""" % (job.id, job.priority + 1) + - """<button title="decrease chunks size" onclick="request('/edit_%s', "{'priority': %i}");" %s>-</button>""" % (job.id, job.priority - 1, "disabled=True" if job.priority == 1 else ""), - "%0.1f%%" % (job.usage * 100), - "%is" % int(time.time() - job.last_dispatched), - job.statusText(), - len(job), - results[DONE], - results[DISPATCHED], - str(results[ERROR]) + - """<button title="reset error frames" onclick="request('/reset_%s_0', null);" %s>R</button>""" % (job.id, "disabled=True" if not results[ERROR] else ""), - handler.server.balancer.applyPriorities(job), handler.server.balancer.applyExceptions(job) - ) + """<button title="cancel job" onclick="request('/cancel_%s', null);">X</button>""" % job.id + + """<button title="reset all frames" onclick="request('/resetall_%s_0', null);">R</button>""" % job.id, + job.id, + link(job.name, "/html/job" + job.id), + job.category if job.category else "<i>None</i>", + str(job.chunks) + + """<button title="increase priority" onclick="request('/edit_%s', "{'chunks': %i}");">+</button>""" % (job.id, job.chunks + 1) + + """<button title="decrease priority" onclick="request('/edit_%s', "{'chunks': %i}");" %s>-</button>""" % (job.id, job.chunks - 1, "disabled=True" if job.chunks == 1 else ""), + str(job.priority) + + """<button title="increase chunks size" onclick="request('/edit_%s', "{'priority': %i}");">+</button>""" % (job.id, job.priority + 1) + + """<button title="decrease chunks size" onclick="request('/edit_%s', "{'priority': %i}");" %s>-</button>""" % (job.id, job.priority - 1, "disabled=True" if job.priority == 1 else ""), + "%0.1f%%" % (job.usage * 100), + "%is" % int(time.time() - job.last_dispatched), + job.statusText(), + len(job), + results[DONE], + results[DISPATCHED], + str(results[ERROR]) + + """<button title="reset error frames" onclick="request('/reset_%s_0', null);" %s>R</button>""" % (job.id, "disabled=True" if not results[ERROR] else ""), + handler.server.balancer.applyPriorities(job), handler.server.balancer.applyExceptions(job) + ) endTable() diff --git a/release/scripts/io/netrender/netrender.js b/release/scripts/io/netrender/netrender.js index 23f9f25c763..e219d80651d 100644 --- a/release/scripts/io/netrender/netrender.js +++ b/release/scripts/io/netrender/netrender.js @@ -11,6 +11,19 @@ function edit(id, info) request("/edit_" + id, info) } +function balance_edit(id, old_value) +{ + var new_value = prompt("New limit", old_value); + if (new_value != null && new_value != "") { + request("/balance_limit", "{" + id + ":'" + new_value + "'}"); + } +} + +function balance_enable(id, value) +{ + request("/balance_enable", "{" + id + ":" + value + "}"); +} + function returnObjById( id ) { if (document.getElementById) |