Netrender: categories and balancing by categories based on usage. Enables grouping of jobs in a single priority group. Jobs in the same category are still ordered by cluster usage.

This commit is contained in:
Martin Poirier
2009-12-10 18:56:21 +00:00
parent 2576268fb8
commit 8f2db59253
6 changed files with 45 additions and 16 deletions

View File

@@ -84,6 +84,16 @@ class RatingUsage(RatingRule):
# less usage is better
return job.usage / job.priority
class RatingUsageByCategory(RatingRule):
def __init__(self, get_jobs):
self.getJobs = get_jobs
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])
# less usage is better
return total_category_usage / maximum_priority
class NewJobPriority(PriorityRule):
def __init__(self, limit = 1):
self.limit = limit

View File

@@ -150,6 +150,7 @@ def clientSendJob(conn, scene, anim = False):
# print(job.files)
job.name = job_name
job.category = netsettings.job_category
for slave in netrender.blacklist:
job.blacklist.append(slave.id)

View File

@@ -60,17 +60,9 @@ class MRenderSlave(netrender.model.RenderSlave):
self.job = None
class MRenderJob(netrender.model.RenderJob):
def __init__(self, job_id, job_type, name, files, chunks = 1, priority = 1, blacklist = []):
super().__init__()
def __init__(self, job_id, job_info):
super().__init__(job_info)
self.id = job_id
self.type = job_type
self.name = name
self.files = files
self.frames = []
self.chunks = chunks
self.priority = priority
self.usage = 0.0
self.blacklist = blacklist
self.last_dispatched = time.time()
# force one chunk for process jobs
@@ -80,7 +72,7 @@ class MRenderJob(netrender.model.RenderJob):
# special server properties
self.last_update = 0
self.save_path = ""
self.files_map = {path: MRenderFile(path, start, end) for path, start, end in files}
self.files_map = {path: MRenderFile(path, start, end) for path, start, end in job_info.files}
self.status = JOB_WAITING
def save(self):
@@ -393,7 +385,7 @@ class RenderHandler(http.server.BaseHTTPRequestHandler):
job_id = self.server.nextJobID()
job = MRenderJob(job_id, job_info.type, job_info.name, job_info.files, chunks = job_info.chunks, priority = job_info.priority, blacklist = job_info.blacklist)
job = MRenderJob(job_id, job_info)
for frame in job_info.frames:
frame = job.addFrame(frame.number, frame.command)
@@ -635,6 +627,7 @@ class RenderMasterServer(http.server.HTTPServer):
self.slave_timeout = 2
self.balancer = netrender.balancing.Balancer()
self.balancer.addRule(netrender.balancing.RatingUsageByCategory(self.getJobs))
self.balancer.addRule(netrender.balancing.RatingUsage())
self.balancer.addException(netrender.balancing.ExcludeQueuedEmptyJob())
self.balancer.addException(netrender.balancing.ExcludeSlavesLimit(self.countJobs, self.countSlaves, limit = 0.9))
@@ -707,6 +700,9 @@ class RenderMasterServer(http.server.HTTPServer):
def balance(self):
self.balancer.balance(self.jobs)
def getJobs(self):
return self.jobs
def countJobs(self, status = JOB_QUEUED):
total = 0
for j in self.jobs:

View File

@@ -71,6 +71,7 @@ def get(handler):
startTable()
headerTable(
"name",
"category",
"priority",
"usage",
"wait",
@@ -88,6 +89,7 @@ def get(handler):
results = job.framesStatus()
rowTable(
link(job.name, "/html/job" + job.id),
job.category,
job.priority,
"%0.1f%%" % (job.usage * 100),
"%is" % int(time.time() - job.last_dispatched),

View File

@@ -99,18 +99,29 @@ JOB_TYPES = {
}
class RenderJob:
def __init__(self):
def __init__(self, job_info = None):
self.id = ""
self.type = JOB_BLENDER
self.name = ""
self.category = "None"
self.files = []
self.frames = []
self.chunks = 0
self.priority = 0
self.usage = 0.0
self.blacklist = []
self.usage = 0.0
self.last_dispatched = 0.0
self.frames = []
if job_info:
self.type = job_info.type
self.name = job_info.name
self.category = job_info.category
self.files = job_info.files
self.chunks = job_info.chunks
self.priority = job_info.priority
self.blacklist = job_info.blacklist
def addFile(self, file_path, start=-1, end=-1):
self.files.append((file_path, start, end))
@@ -167,6 +178,7 @@ class RenderJob:
"id": self.id,
"type": self.type,
"name": self.name,
"category": self.category,
"files": [f for f in self.files if f[1] == -1 or not frames or (f[1] <= max_frame and f[2] >= min_frame)],
"frames": [f.serialize() for f in self.frames if not frames or f in frames],
"chunks": self.chunks,
@@ -185,6 +197,7 @@ class RenderJob:
job.id = data["id"]
job.type = data["type"]
job.name = data["name"]
job.category = data["category"]
job.files = data["files"]
job.frames = [RenderFrame.materialize(f) for f in data["frames"]]
job.chunks = data["chunks"]

View File

@@ -97,6 +97,7 @@ class RENDER_PT_network_job(RenderButtonsPanel):
col.operator("render.netclientsend", icon='FILE_BLEND')
col.operator("render.netclientweb", icon='QUESTION')
col.prop(scene.network_render, "job_name")
col.prop(scene.network_render, "job_category")
row = col.row()
row.prop(scene.network_render, "priority")
row.prop(scene.network_render, "chunks")
@@ -264,6 +265,12 @@ NetRenderSettings.StringProperty( attr="job_name",
maxlen = 128,
default = "[default]")
NetRenderSettings.StringProperty( attr="job_category",
name="Job category",
description="Category of the job",
maxlen = 128,
default = "")
NetRenderSettings.IntProperty( attr="chunks",
name="Chunks",
description="Number of frame to dispatch to each slave in one chunk",