Revision: 23594 http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=23594 Author: theeth Date: 2009-10-01 20:57:22 +0200 (Thu, 01 Oct 2009)
Log Message: ----------- netrender: first draft for process jobs, to be able to run arbitrary commands on slaves. This could be used to bake physics on network or whatnot. Modified Paths: -------------- trunk/blender/release/scripts/io/netrender/client.py trunk/blender/release/scripts/io/netrender/master.py trunk/blender/release/scripts/io/netrender/master_html.py trunk/blender/release/scripts/io/netrender/model.py trunk/blender/release/scripts/io/netrender/slave.py Modified: trunk/blender/release/scripts/io/netrender/client.py =================================================================== --- trunk/blender/release/scripts/io/netrender/client.py 2009-10-01 18:30:59 UTC (rev 23593) +++ trunk/blender/release/scripts/io/netrender/client.py 2009-10-01 18:57:22 UTC (rev 23594) @@ -3,12 +3,12 @@ import http, http.client, http.server, urllib import subprocess, shutil, time, hashlib +import netrender.model import netrender.slave as slave import netrender.master as master from netrender.utils import * - -def clientSendJob(conn, scene, anim = False, chunks = 5): +def clientSendJob(conn, scene, anim = False): netsettings = scene.network_render job = netrender.model.RenderJob() Modified: trunk/blender/release/scripts/io/netrender/master.py =================================================================== --- trunk/blender/release/scripts/io/netrender/master.py 2009-10-01 18:30:59 UTC (rev 23593) +++ trunk/blender/release/scripts/io/netrender/master.py 2009-10-01 18:57:22 UTC (rev 23594) @@ -42,9 +42,10 @@ self.job = None class MRenderJob(netrender.model.RenderJob): - def __init__(self, job_id, name, files, chunks = 1, priority = 1, blacklist = []): + def __init__(self, job_id, job_type, name, files, chunks = 1, priority = 1, blacklist = []): super().__init__() self.id = job_id + self.type = job_type self.name = name self.files = files self.frames = [] @@ -53,6 +54,10 @@ self.usage = 0.0 self.blacklist = blacklist self.last_dispatched = time.time() + + # force one chunk for process jobs + if self.type == netrender.model.JOB_PROCESS: + self.chunks = 1 # special server properties self.last_update = 0 @@ -93,8 +98,8 @@ if frame: frame.log_path = log_path - def addFrame(self, frame_number): - frame = MRenderFrame(frame_number) + def addFrame(self, frame_number, command): + frame = MRenderFrame(frame_number, command) self.frames.append(frame) return frame @@ -114,12 +119,14 @@ return frames class MRenderFrame(netrender.model.RenderFrame): - def __init__(self, frame): + def __init__(self, frame, command): super().__init__() self.number = frame self.slave = None self.time = 0 self.status = QUEUED + self.command = command + self.log_path = None def reset(self, all): @@ -368,10 +375,10 @@ job_id = self.server.nextJobID() - job = MRenderJob(job_id, job_info.name, job_info.files, chunks = job_info.chunks, priority = job_info.priority, blacklist = job_info.blacklist) + 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) for frame in job_info.frames: - frame = job.addFrame(frame.number) + frame = job.addFrame(frame.number, frame.command) self.server.addJob(job) @@ -538,17 +545,18 @@ frame = job[job_frame] if frame: - if job_result == DONE: - length = int(self.headers['content-length']) - buf = self.rfile.read(length) - f = open(job.save_path + "%04d" % job_frame + ".exr", 'wb') - f.write(buf) - f.close() + if job.type == netrender.model.JOB_BLENDER: + if job_result == DONE: + length = int(self.headers['content-length']) + buf = self.rfile.read(length) + f = open(job.save_path + "%04d" % job_frame + ".exr", 'wb') + f.write(buf) + f.close() - del buf - elif job_result == ERROR: - # blacklist slave on this job on error - job.blacklist.append(slave.id) + del buf + elif job_result == ERROR: + # blacklist slave on this job on error + job.blacklist.append(slave.id) self.server.stats("", "Receiving result") Modified: trunk/blender/release/scripts/io/netrender/master_html.py =================================================================== --- trunk/blender/release/scripts/io/netrender/master_html.py 2009-10-01 18:30:59 UTC (rev 23593) +++ trunk/blender/release/scripts/io/netrender/master_html.py 2009-10-01 18:57:22 UTC (rev 23594) @@ -32,9 +32,8 @@ def endTable(): output("</table>") - handler.send_head(content = "text/html") - if handler.path == "/html" or handler.path == "/": + handler.send_head(content = "text/html") output("<html><head><title>NetRender</title></head><body>") output("<h2>Master</h2>") @@ -86,6 +85,7 @@ output("</body></html>") elif handler.path.startswith("/html/job"): + handler.send_head(content = "text/html") job_id = handler.path[9:] output("<html><head><title>NetRender</title></head><body>") @@ -108,10 +108,9 @@ output("</body></html>") elif handler.path.startswith("/html/log"): + handler.send_head(content = "text/plain") pattern = re.compile("([a-zA-Z0-9]+)_([0-9]+)") - output("<html><head><title>NetRender</title></head><body>") - match = pattern.match(handler.path[9:]) if match: job_id = match.groups()[0] @@ -125,12 +124,8 @@ if frame: f = open(frame.log_path, 'rb') - output("<pre>") - shutil.copyfileobj(f, handler.wfile) - output("</pre>") - f.close() else: output("no such frame") @@ -138,5 +133,3 @@ output("no such job") else: output("malformed url") - - output("</body></html>") Modified: trunk/blender/release/scripts/io/netrender/model.py =================================================================== --- trunk/blender/release/scripts/io/netrender/model.py 2009-10-01 18:30:59 UTC (rev 23593) +++ trunk/blender/release/scripts/io/netrender/model.py 2009-10-01 18:57:22 UTC (rev 23594) @@ -72,9 +72,18 @@ return slave +JOB_BLENDER = 1 +JOB_PROCESS = 2 + +JOB_TYPES = { + JOB_BLENDER: "Blender", + JOB_PROCESS: "Process" + } + class RenderJob: def __init__(self): self.id = "" + self.type = JOB_BLENDER self.name = "" self.files = [] self.frames = [] @@ -87,8 +96,8 @@ def addFile(self, file_path, start=-1, end=-1): self.files.append((file_path, start, end)) - def addFrame(self, frame_number): - frame = RenderFrame(frame_number) + def addFrame(self, frame_number, command = ""): + frame = RenderFrame(frame_number, command) self.frames.append(frame) return frame @@ -138,6 +147,7 @@ max_frame = max((f.number for f in frames)) if frames else -1 return { "id": self.id, + "type": self.type, "name": self.name, "files": [f for f in self.files if f[1] == -1 or not frames or (f[1] <= min_frame <= f[2] or f[1] <= max_frame <= f[2])], "frames": [f.serialize() for f in self.frames if not frames or f in frames], @@ -155,6 +165,7 @@ job = RenderJob() job.id = data["id"] + job.type = data["type"] job.name = data["name"] job.files = data["files"] job.frames = [RenderFrame.materialize(f) for f in data["frames"]] @@ -167,11 +178,12 @@ return job class RenderFrame: - def __init__(self, number = 0): + def __init__(self, number = 0, command = ""): self.number = number self.time = 0 self.status = QUEUED self.slave = None + self.command = command def statusText(self): return STATUS_TEXT[self.status] @@ -181,7 +193,8 @@ "number": self.number, "time": self.time, "status": self.status, - "slave": None if not self.slave else self.slave.serialize() + "slave": None if not self.slave else self.slave.serialize(), + "command": self.command } @staticmethod @@ -194,5 +207,6 @@ frame.time = data["time"] frame.status = data["status"] frame.slave = RenderSlave.materialize(data["slave"]) + frame.command = data["command"] return frame Modified: trunk/blender/release/scripts/io/netrender/slave.py =================================================================== --- trunk/blender/release/scripts/io/netrender/slave.py 2009-10-01 18:30:59 UTC (rev 23593) +++ trunk/blender/release/scripts/io/netrender/slave.py 2009-10-01 18:57:22 UTC (rev 23594) @@ -99,38 +99,47 @@ if not os.path.exists(JOB_PREFIX): os.mkdir(JOB_PREFIX) - job_path = job.files[0][0] # data in files have format (path, start, end) - main_path, main_file = os.path.split(job_path) - job_full_path = testFile(conn, job.id, slave_id, JOB_PREFIX, job_path) - print("Fullpath", job_full_path) - print("File:", main_file, "and %i other files" % (len(job.files) - 1,)) - engine.update_stats("", "Render File", main_file, "for job", job.id) - - for file_path, start, end in job.files[1:]: - print("\t", file_path) - testFile(conn, job.id, slave_id, JOB_PREFIX, file_path, main_path) - - frame_args = [] - - for frame in job.frames: - print("frame", frame.number) - frame_args += ["-f", str(frame.number)] - + if job.type == netrender.model.JOB_BLENDER: + job_path = job.files[0][0] # data in files have format (path, start, end) + main_path, main_file = os.path.split(job_path) + + job_full_path = testFile(conn, job.id, slave_id, JOB_PREFIX, job_path) + print("Fullpath", job_full_path) + print("File:", main_file, "and %i other files" % (len(job.files) - 1,)) + engine.update_stats("", "Render File", main_file, "for job", job.id) + + for file_path, start, end in job.files[1:]: + print("\t", file_path) + testFile(conn, job.id, slave_id, JOB_PREFIX, file_path, main_path) + # announce log to master logfile = netrender.model.LogFile(job.id, [frame.number for frame in job.frames]) conn.request("POST", "/log", bytes(repr(logfile.serialize()), encoding='utf8'), headers={"slave-id":slave_id}) response = conn.getresponse() + first_frame = job.frames[0].number - + # start render start_t = time.time() + + if job.type == netrender.model.JOB_BLENDER: + frame_args = [] + + for frame in job.frames: + print("frame", frame.number) + frame_args += ["-f", str(frame.number)] + + val = SetErrorMode() + process = subprocess.Popen([sys.argv[0], "-b", job_full_path, "-o", JOB_PREFIX + "######", "-E", "BLENDER_RENDER", "-F", "MULTILAYER"] + frame_args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + RestoreErrorMode(val) + elif job.type == netrender.model.JOB_PROCESS: + command = job.frames[0].command + val = SetErrorMode() @@ Diff output truncated at 10240 characters. @@ _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org http://lists.blender.org/mailman/listinfo/bf-blender-cvs