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

Reply via email to