Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Poirier <theeth@yahoo.com>2009-12-15 02:09:08 +0300
committerMartin Poirier <theeth@yahoo.com>2009-12-15 02:09:08 +0300
commit8828f92aad122bf5585a4ab2f0a33934e8b578ac (patch)
tree40e91d722e16cd1ae793abcf86ee0f7a5654d980
parent03e1afe7ac4d507bf8a41e42049d618313599ab6 (diff)
Netrender internal refactor.
use a real object for files instead of a tuple unique urls for files, logs and render results (just missing the proper mime type for exr files) fix bug with slaves not getting the correct machine name
-rw-r--r--release/scripts/io/netrender/client.py13
-rw-r--r--release/scripts/io/netrender/master.py279
-rw-r--r--release/scripts/io/netrender/master_html.py34
-rw-r--r--release/scripts/io/netrender/model.py64
-rw-r--r--release/scripts/io/netrender/slave.py29
-rw-r--r--release/scripts/io/netrender/utils.py11
6 files changed, 234 insertions, 196 deletions
diff --git a/release/scripts/io/netrender/client.py b/release/scripts/io/netrender/client.py
index 829d75b6c67..a203d137174 100644
--- a/release/scripts/io/netrender/client.py
+++ b/release/scripts/io/netrender/client.py
@@ -106,7 +106,6 @@ def clientSendJob(conn, scene, anim = False):
job_name = netsettings.job_name
path, name = os.path.split(filename)
- path += os.sep
if job_name == "[default]":
job_name = name
@@ -147,7 +146,7 @@ def clientSendJob(conn, scene, anim = False):
for psys in object.particle_systems:
addPointCache(job, object, psys.point_cache, default_path)
- # print(job.files)
+ #print(job.files)
job.name = job_name
job.category = netsettings.job_category
@@ -166,18 +165,18 @@ def clientSendJob(conn, scene, anim = False):
# if not ACCEPTED (but not processed), send files
if response.status == http.client.ACCEPTED:
- for filepath, start, end in job.files:
- f = open(filepath, "rb")
- conn.request("PUT", "/file", f, headers={"job-id": job_id, "job-file": filepath})
+ for rfile in job.files:
+ f = open(rfile.filepath, "rb")
+ conn.request("PUT", fileURL(job_id, rfile.index), f)
f.close()
response = conn.getresponse()
- # server will reply with NOT_FOUD until all files are found
+ # server will reply with ACCEPTED until all files are found
return job_id
def requestResult(conn, job_id, frame):
- conn.request("GET", "/render", headers={"job-id": job_id, "job-frame":str(frame)})
+ conn.request("GET", renderURL(job_id, frame))
@rnaType
class NetworkRenderEngine(bpy.types.RenderEngine):
diff --git a/release/scripts/io/netrender/master.py b/release/scripts/io/netrender/master.py
index 504430a7e0c..7e374afd6ab 100644
--- a/release/scripts/io/netrender/master.py
+++ b/release/scripts/io/netrender/master.py
@@ -25,11 +25,9 @@ import netrender.model
import netrender.balancing
import netrender.master_html
-class MRenderFile:
- def __init__(self, filepath, start, end):
- self.filepath = filepath
- self.start = start
- self.end = end
+class MRenderFile(netrender.model.RenderFile):
+ def __init__(self, filepath, index, start, end):
+ super().__init__(filepath, index, start, end)
self.found = False
def test(self):
@@ -72,7 +70,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 job_info.files}
+ self.files = [MRenderFile(rfile.filepath, rfile.index, rfile.start, rfile.end) for rfile in job_info.files]
self.status = JOB_WAITING
def save(self):
@@ -82,7 +80,7 @@ class MRenderJob(netrender.model.RenderJob):
f.close()
def testStart(self):
- for f in self.files_map.values():
+ for f in self.files:
if not f.test():
return False
@@ -150,6 +148,9 @@ class MRenderFrame(netrender.model.RenderFrame):
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
# -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+file_pattern = re.compile("/file_([a-zA-Z0-9]+)_([0-9]+)")
+render_pattern = re.compile("/render_([a-zA-Z0-9]+)_([0-9]+).exr")
+log_pattern = re.compile("/log_([a-zA-Z0-9]+)_([0-9]+).log")
class RenderHandler(http.server.BaseHTTPRequestHandler):
def send_head(self, code = http.client.OK, headers = {}, content = "application/octet-stream"):
@@ -194,62 +195,74 @@ class RenderHandler(http.server.BaseHTTPRequestHandler):
self.server.stats("", "Version check")
self.wfile.write(VERSION)
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
- elif self.path == "/render":
- job_id = self.headers['job-id']
- job_frame = int(self.headers['job-frame'])
+ elif self.path.startswith("/render"):
+ match = render_pattern.match(self.path)
- job = self.server.getJobID(job_id)
+ if match:
+ job_id = match.groups()[0]
+ frame_number = int(match.groups()[1])
- if job:
- frame = job[job_frame]
+ job = self.server.getJobID(job_id)
- if frame:
- if frame.status in (QUEUED, DISPATCHED):
- self.send_head(http.client.ACCEPTED)
- elif frame.status == DONE:
- self.server.stats("", "Sending result to client")
- f = open(job.save_path + "%04d" % job_frame + ".exr", 'rb')
-
- self.send_head()
-
- shutil.copyfileobj(f, self.wfile)
-
- f.close()
- elif frame.status == ERROR:
- self.send_head(http.client.PARTIAL_CONTENT)
+ if job:
+ frame = job[frame_number]
+
+ if frame:
+ if frame.status in (QUEUED, DISPATCHED):
+ self.send_head(http.client.ACCEPTED)
+ elif frame.status == DONE:
+ self.server.stats("", "Sending result to client")
+ f = open(job.save_path + "%04d" % frame_number + ".exr", 'rb')
+
+ self.send_head()
+
+ shutil.copyfileobj(f, self.wfile)
+
+ f.close()
+ elif frame.status == ERROR:
+ self.send_head(http.client.PARTIAL_CONTENT)
+ else:
+ # no such frame
+ self.send_head(http.client.NO_CONTENT)
else:
- # no such frame
+ # no such job id
self.send_head(http.client.NO_CONTENT)
else:
- # no such job id
+ # invalid url
self.send_head(http.client.NO_CONTENT)
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
- elif self.path == "/log":
- job_id = self.headers['job-id']
- job_frame = int(self.headers['job-frame'])
-
- job = self.server.getJobID(job_id)
+ elif self.path.startswith("/log"):
+ match = log_pattern.match(self.path)
- if job:
- frame = job[job_frame]
+ if match:
+ job_id = match.groups()[0]
+ frame_number = int(match.groups()[1])
- if frame:
- if not frame.log_path or frame.status in (QUEUED, DISPATCHED):
- self.send_head(http.client.PROCESSING)
+ job = self.server.getJobID(job_id)
+
+ if job:
+ frame = job[frame_number]
+
+ if frame:
+ if not frame.log_path or frame.status in (QUEUED, DISPATCHED):
+ self.send_head(http.client.PROCESSING)
+ else:
+ self.server.stats("", "Sending log to client")
+ f = open(frame.log_path, 'rb')
+
+ self.send_head(content = "text/plain")
+
+ shutil.copyfileobj(f, self.wfile)
+
+ f.close()
else:
- self.server.stats("", "Sending log to client")
- f = open(frame.log_path, 'rb')
-
- self.send_head()
-
- shutil.copyfileobj(f, self.wfile)
-
- f.close()
+ # no such frame
+ self.send_head(http.client.NO_CONTENT)
else:
- # no such frame
+ # no such job id
self.send_head(http.client.NO_CONTENT)
else:
- # no such job id
+ # invalid URL
self.send_head(http.client.NO_CONTENT)
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
elif self.path == "/status":
@@ -322,19 +335,24 @@ class RenderHandler(http.server.BaseHTTPRequestHandler):
else: # invalid slave id
self.send_head(http.client.NO_CONTENT)
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
- elif self.path == "/file":
- slave_id = self.headers['slave-id']
-
- slave = self.server.getSeenSlave(slave_id)
+ elif self.path.startswith("/file"):
+ match = file_pattern.match(self.path)
- if slave: # only if slave id is valid
- job_id = self.headers['job-id']
- job_file = self.headers['job-file']
+ if match:
+ slave_id = self.headers['slave-id']
+ slave = self.server.getSeenSlave(slave_id)
+
+ if not slave:
+ # invalid slave id
+ print("invalid slave id")
+
+ job_id = match.groups()[0]
+ file_index = int(match.groups()[1])
job = self.server.getJobID(job_id)
if job:
- render_file = job.files_map.get(job_file, None)
+ render_file = job.files[file_index]
if render_file:
self.server.stats("", "Sending file to slave")
@@ -350,7 +368,7 @@ class RenderHandler(http.server.BaseHTTPRequestHandler):
else:
# no such job id
self.send_head(http.client.NO_CONTENT)
- else: # invalid slave id
+ else: # invalid url
self.send_head(http.client.NO_CONTENT)
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
elif self.path == "/slaves":
@@ -395,10 +413,10 @@ class RenderHandler(http.server.BaseHTTPRequestHandler):
headers={"job-id": job_id}
if job.testStart():
- self.server.stats("", "New job, missing files")
+ self.server.stats("", "New job, started")
self.send_head(headers=headers)
else:
- self.server.stats("", "New job, started")
+ self.server.stats("", "New job, missing files (%i total)" % len(job.files))
self.send_head(http.client.ACCEPTED, headers=headers)
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
elif self.path == "/cancel":
@@ -455,22 +473,22 @@ class RenderHandler(http.server.BaseHTTPRequestHandler):
self.server.stats("", "New slave connected")
- slave_info = netrender.model.RenderSlave.materialize(eval(str(self.rfile.read(length), encoding='utf8')))
+ slave_info = netrender.model.RenderSlave.materialize(eval(str(self.rfile.read(length), encoding='utf8')), cache = False)
slave_id = self.server.addSlave(slave_info.name, self.client_address, slave_info.stats)
self.send_head(headers = {"slave-id": slave_id})
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
elif self.path == "/log":
- slave_id = self.headers['slave-id']
+ length = int(self.headers['content-length'])
+
+ log_info = netrender.model.LogFile.materialize(eval(str(self.rfile.read(length), encoding='utf8')))
+
+ slave_id = log_info.slave_id
slave = self.server.getSeenSlave(slave_id)
if slave: # only if slave id is valid
- length = int(self.headers['content-length'])
-
- log_info = netrender.model.LogFile.materialize(eval(str(self.rfile.read(length), encoding='utf8')))
-
job = self.server.getJobID(log_info.job_id)
if job:
@@ -490,49 +508,57 @@ class RenderHandler(http.server.BaseHTTPRequestHandler):
def do_PUT(self):
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
- if self.path == "/file":
- self.server.stats("", "Receiving job")
+ if self.path.startswith("/file"):
+ match = file_pattern.match(self.path)
- length = int(self.headers['content-length'])
- job_id = self.headers['job-id']
- job_file = self.headers['job-file']
-
- job = self.server.getJobID(job_id)
+ if match:
+ self.server.stats("", "Receiving job")
+
+ length = int(self.headers['content-length'])
+ job_id = match.groups()[0]
+ file_index = int(match.groups()[1])
- if job:
-
- render_file = job.files_map.get(job_file, None)
+ job = self.server.getJobID(job_id)
- if render_file:
- main_file = job.files[0][0] # filename of the first file
-
- main_path, main_name = os.path.split(main_file)
-
- if job_file != main_file:
- file_path = prefixPath(job.save_path, job_file, main_path)
- else:
- file_path = job.save_path + main_name
-
- buf = self.rfile.read(length)
-
- # add same temp file + renames as slave
-
- f = open(file_path, "wb")
- f.write(buf)
- f.close()
- del buf
+ if job:
- render_file.filepath = file_path # set the new path
+ render_file = job.files[file_index]
- if job.testStart():
- self.server.stats("", "File upload, starting job")
- self.send_head(http.client.OK)
- else:
- self.server.stats("", "File upload, file missings")
- self.send_head(http.client.ACCEPTED)
- else: # invalid file
+ if render_file:
+ main_file = job.files[0].filepath # filename of the first file
+
+ main_path, main_name = os.path.split(main_file)
+
+ if file_index > 0:
+ file_path = prefixPath(job.save_path, render_file.filepath, main_path)
+ else:
+ file_path = job.save_path + main_name
+
+ buf = self.rfile.read(length)
+
+ # add same temp file + renames as slave
+
+ f = open(file_path, "wb")
+ f.write(buf)
+ f.close()
+ del buf
+
+ render_file.filepath = file_path # set the new path
+
+ if job.testStart():
+ self.server.stats("", "File upload, starting job")
+ self.send_head(http.client.OK)
+ else:
+ self.server.stats("", "File upload, file missings")
+ self.send_head(http.client.ACCEPTED)
+ else: # invalid file
+ print("file not found", job_id, file_index)
+ self.send_head(http.client.NO_CONTENT)
+ else: # job not found
+ print("job not found", job_id, file_index)
self.send_head(http.client.NO_CONTENT)
- else: # job not found
+ else: # invalid url
+ print("no match")
self.send_head(http.client.NO_CONTENT)
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
elif self.path == "/render":
@@ -585,33 +611,38 @@ class RenderHandler(http.server.BaseHTTPRequestHandler):
else: # invalid slave id
self.send_head(http.client.NO_CONTENT)
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
- elif self.path == "/log":
+ elif self.path.startswith("/log"):
self.server.stats("", "Receiving log file")
+
+ match = log_pattern.match(self.path)
- job_id = self.headers['job-id']
-
- job = self.server.getJobID(job_id)
-
- if job:
- job_frame = int(self.headers['job-frame'])
+ if match:
+ job_id = match.groups()[0]
- frame = job[job_frame]
+ job = self.server.getJobID(job_id)
- if frame and frame.log_path:
- length = int(self.headers['content-length'])
- buf = self.rfile.read(length)
- f = open(frame.log_path, 'ab')
- f.write(buf)
- f.close()
-
- del buf
+ if job:
+ job_frame = int(match.groups()[1])
- self.server.getSeenSlave(self.headers['slave-id'])
+ frame = job[job_frame]
- self.send_head()
- else: # frame not found
+ if frame and frame.log_path:
+ length = int(self.headers['content-length'])
+ buf = self.rfile.read(length)
+ f = open(frame.log_path, 'ab')
+ f.write(buf)
+ f.close()
+
+ del buf
+
+ self.server.getSeenSlave(self.headers['slave-id'])
+
+ self.send_head()
+ else: # frame not found
+ self.send_head(http.client.NO_CONTENT)
+ else: # job not found
self.send_head(http.client.NO_CONTENT)
- else: # job not found
+ else: # invalid url
self.send_head(http.client.NO_CONTENT)
class RenderMasterServer(http.server.HTTPServer):
@@ -624,7 +655,7 @@ class RenderMasterServer(http.server.HTTPServer):
self.job_id = 0
self.path = path + "master_" + str(os.getpid()) + os.sep
- self.slave_timeout = 2
+ self.slave_timeout = 30 # 30 mins: need a parameter for that
self.balancer = netrender.balancing.Balancer()
self.balancer.addRule(netrender.balancing.RatingUsageByCategory(self.getJobs))
diff --git a/release/scripts/io/netrender/master_html.py b/release/scripts/io/netrender/master_html.py
index c94d1e2f72d..c08dc07724d 100644
--- a/release/scripts/io/netrender/master_html.py
+++ b/release/scripts/io/netrender/master_html.py
@@ -89,7 +89,7 @@ def get(handler):
results = job.framesStatus()
rowTable(
link(job.name, "/html/job" + job.id),
- job.category,
+ job.category if job.category else "&nbsp;",
job.priority,
"%0.1f%%" % (job.usage * 100),
"%is" % int(time.time() - job.last_dispatched),
@@ -116,40 +116,14 @@ def get(handler):
output("<h2>Frames</h2>")
startTable()
- headerTable("no", "status", "render time", "slave", "log")
+ headerTable("no", "status", "render time", "slave", "log", "result")
for frame in job.frames:
- rowTable(frame.number, frame.statusText(), "%.1fs" % frame.time, frame.slave.name if frame.slave else "&nbsp;", link("view log", "/html/log%s_%i" % (job_id, frame.number)) if frame.log_path else "&nbsp;")
+ rowTable(frame.number, frame.statusText(), "%.1fs" % frame.time, frame.slave.name if frame.slave else "&nbsp;", link("view log", logURL(job_id, frame.number)) if frame.log_path else "&nbsp;", link("view result", renderURL(job_id, frame.number)) if frame.status == DONE else "&nbsp;")
endTable()
else:
output("no such job")
output("</body></html>")
-
- elif handler.path.startswith("/html/log"):
- handler.send_head(content = "text/plain")
- pattern = re.compile("([a-zA-Z0-9]+)_([0-9]+)")
-
- match = pattern.match(handler.path[9:])
- if match:
- job_id = match.groups()[0]
- frame_number = int(match.groups()[1])
-
- job = handler.server.getJobID(job_id)
-
- if job:
- frame = job[frame_number]
-
- if frame:
- f = open(frame.log_path, 'rb')
-
- shutil.copyfileobj(f, handler.wfile)
-
- f.close()
- else:
- output("no such frame")
- else:
- output("no such job")
- else:
- output("malformed url")
+
diff --git a/release/scripts/io/netrender/model.py b/release/scripts/io/netrender/model.py
index 7d0fff5a83a..b731b32481e 100644
--- a/release/scripts/io/netrender/model.py
+++ b/release/scripts/io/netrender/model.py
@@ -23,13 +23,15 @@ import subprocess, shutil, time, hashlib
from netrender.utils import *
class LogFile:
- def __init__(self, job_id = 0, frames = []):
+ def __init__(self, job_id = 0, slave_id = 0, frames = []):
self.job_id = job_id
+ self.slave_id = slave_id
self.frames = frames
def serialize(self):
return {
"job_id": self.job_id,
+ "slave_id": self.slave_id,
"frames": self.frames
}
@@ -40,6 +42,7 @@ class LogFile:
logfile = LogFile()
logfile.job_id = data["job_id"]
+ logfile.slave_id = data["slave_id"]
logfile.frames = data["frames"]
return logfile
@@ -68,27 +71,28 @@ class RenderSlave:
}
@staticmethod
- def materialize(data):
+ def materialize(data, cache = True):
if not data:
return None
slave_id = data["id"]
-
- if slave_id in RenderSlave._slave_map:
+
+ if cache and slave_id in RenderSlave._slave_map:
return RenderSlave._slave_map[slave_id]
- else:
- slave = RenderSlave()
- slave.id = slave_id
- slave.name = data["name"]
- slave.address = data["address"]
- slave.stats = data["stats"]
- slave.total_done = data["total_done"]
- slave.total_error = data["total_error"]
- slave.last_seen = data["last_seen"]
-
+
+ slave = RenderSlave()
+ slave.id = slave_id
+ slave.name = data["name"]
+ slave.address = data["address"]
+ slave.stats = data["stats"]
+ slave.total_done = data["total_done"]
+ slave.total_error = data["total_error"]
+ slave.last_seen = data["last_seen"]
+
+ if cache:
RenderSlave._slave_map[slave_id] = slave
- return slave
+ return slave
JOB_BLENDER = 1
JOB_PROCESS = 2
@@ -98,6 +102,30 @@ JOB_TYPES = {
JOB_PROCESS: "Process"
}
+class RenderFile:
+ def __init__(self, filepath = "", index = 0, start = -1, end = -1):
+ self.filepath = filepath
+ self.index = index
+ self.start = start
+ self.end = end
+
+ def serialize(self):
+ return {
+ "filepath": self.filepath,
+ "index": self.index,
+ "start": self.start,
+ "end": self.end
+ }
+
+ @staticmethod
+ def materialize(data):
+ if not data:
+ return None
+
+ rfile = RenderFile(data["filepath"], data["index"], data["start"], data["end"])
+
+ return rfile
+
class RenderJob:
def __init__(self, job_info = None):
self.id = ""
@@ -123,7 +151,7 @@ class RenderJob:
self.blacklist = job_info.blacklist
def addFile(self, file_path, start=-1, end=-1):
- self.files.append((file_path, start, end))
+ self.files.append(RenderFile(file_path, len(self.files), start, end))
def addFrame(self, frame_number, command = ""):
frame = RenderFrame(frame_number, command)
@@ -179,7 +207,7 @@ class RenderJob:
"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)],
+ "files": [f.serialize() for f in self.files if f.start == -1 or not frames or (f.start <= max_frame and f.end >= min_frame)],
"frames": [f.serialize() for f in self.frames if not frames or f in frames],
"chunks": self.chunks,
"priority": self.priority,
@@ -198,7 +226,7 @@ class RenderJob:
job.type = data["type"]
job.name = data["name"]
job.category = data["category"]
- job.files = data["files"]
+ job.files = [RenderFile.materialize(f) for f in data["files"]]
job.frames = [RenderFrame.materialize(f) for f in data["frames"]]
job.chunks = data["chunks"]
job.priority = data["priority"]
diff --git a/release/scripts/io/netrender/slave.py b/release/scripts/io/netrender/slave.py
index 74fc44e23d2..9d7fa4fb6b8 100644
--- a/release/scripts/io/netrender/slave.py
+++ b/release/scripts/io/netrender/slave.py
@@ -62,12 +62,12 @@ def testCancel(conn, job_id, frame_number):
else:
return False
-def testFile(conn, job_id, slave_id, JOB_PREFIX, file_path, main_path = None):
+def testFile(conn, job_id, slave_id, file_index, JOB_PREFIX, file_path, main_path = None):
job_full_path = prefixPath(JOB_PREFIX, file_path, main_path)
if not os.path.exists(job_full_path):
temp_path = JOB_PREFIX + "slave.temp.blend"
- conn.request("GET", "/file", headers={"job-id": job_id, "slave-id":slave_id, "job-file":file_path})
+ conn.request("GET", fileURL(job_id, file_index), headers={"slave-id":slave_id})
response = conn.getresponse()
if response.status != http.client.OK:
@@ -86,7 +86,6 @@ def testFile(conn, job_id, slave_id, JOB_PREFIX, file_path, main_path = None):
return job_full_path
-
def render_slave(engine, netsettings):
timeout = 1
@@ -120,21 +119,21 @@ def render_slave(engine, netsettings):
if job.type == netrender.model.JOB_BLENDER:
- job_path = job.files[0][0] # data in files have format (path, start, end)
+ job_path = job.files[0].filepath # path of main file
main_path, main_file = os.path.split(job_path)
- job_full_path = testFile(conn, job.id, slave_id, JOB_PREFIX, job_path)
+ job_full_path = testFile(conn, job.id, slave_id, 0, 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)
+ for rfile in job.files[1:]:
+ print("\t", rfile.filepath)
+ testFile(conn, job.id, slave_id, rfile.index, JOB_PREFIX, rfile.filepath, 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})
+ logfile = netrender.model.LogFile(job.id, slave_id, [frame.number for frame in job.frames])
+ conn.request("POST", "/log", bytes(repr(logfile.serialize()), encoding='utf8'))
response = conn.getresponse()
@@ -151,7 +150,7 @@ def render_slave(engine, netsettings):
frame_args += ["-f", str(frame.number)]
val = SetErrorMode()
- process = subprocess.Popen([BLENDER_PATH, "-b", job_full_path, "-o", JOB_PREFIX + "######", "-E", "BLENDER_RENDER", "-F", "MULTILAYER"] + frame_args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+ process = subprocess.Popen([BLENDER_PATH, "-b", "-noaudio", 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
@@ -159,7 +158,7 @@ def render_slave(engine, netsettings):
process = subprocess.Popen(command.split(" "), stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
RestoreErrorMode(val)
- headers = {"job-id":job.id, "slave-id":slave_id}
+ headers = {"slave-id":slave_id}
cancelled = False
stdout = bytes()
@@ -173,8 +172,7 @@ def render_slave(engine, netsettings):
# update logs if needed
if stdout:
# (only need to update on one frame, they are linked
- headers["job-frame"] = str(first_frame)
- conn.request("PUT", "/log", stdout, headers=headers)
+ conn.request("PUT", logURL(job.id, first_frame), stdout, headers=headers)
response = conn.getresponse()
stdout = bytes()
@@ -203,8 +201,7 @@ def render_slave(engine, netsettings):
# flush the rest of the logs
if stdout:
# (only need to update on one frame, they are linked
- headers["job-frame"] = str(first_frame)
- conn.request("PUT", "/log", stdout, headers=headers)
+ conn.request("PUT", logURL(job.id, first_frame), stdout, headers=headers)
response = conn.getresponse()
headers = {"job-id":job.id, "slave-id":slave_id, "job-time":str(avg_t)}
diff --git a/release/scripts/io/netrender/utils.py b/release/scripts/io/netrender/utils.py
index e549e872398..61a2bb83887 100644
--- a/release/scripts/io/netrender/utils.py
+++ b/release/scripts/io/netrender/utils.py
@@ -28,7 +28,7 @@ try:
except:
bpy = None
-VERSION = b"0.5"
+VERSION = b"0.7"
# Jobs status
JOB_WAITING = 0 # before all data has been entered
@@ -109,6 +109,15 @@ def clientVerifyVersion(conn):
return True
+def fileURL(job_id, file_index):
+ return "/file_%s_%i" % (job_id, file_index)
+
+def logURL(job_id, frame_number):
+ return "/log_%s_%i.log" % (job_id, frame_number)
+
+def renderURL(job_id, frame_number):
+ return "/render_%s_%i.exr" % (job_id, frame_number)
+
def prefixPath(prefix_directory, file_path, prefix_path):
if os.path.isabs(file_path):
# if an absolute path, make sure path exists, if it doesn't, use relative local path