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-09-15 23:53:18 +0400
committerMartin Poirier <theeth@yahoo.com>2009-09-15 23:53:18 +0400
commit22274d38079f7e1e1e0bf24e777c333961ed18f7 (patch)
tree849ef065632c6a3c32a5b84067b6f357e784d3e1 /release
parentfd664970f17b71764753ffe3fb87388f40c91da2 (diff)
More automatic stuff.
Server can now be set to broadcast on local network (every 10s, approximately 20 bytes of data) where client and slave can pick up its existence. This is on by default. Default ip address is now "[default]", which means for the master that it will listen to all interface and for the clients and slave that they will automatically work out the master's address from its broadcast.
Diffstat (limited to 'release')
-rw-r--r--release/io/netrender/client.py13
-rw-r--r--release/io/netrender/master.py24
-rw-r--r--release/io/netrender/operators.py41
-rw-r--r--release/io/netrender/slave.py27
-rw-r--r--release/io/netrender/ui.py24
-rw-r--r--release/io/netrender/utils.py7
6 files changed, 110 insertions, 26 deletions
diff --git a/release/io/netrender/client.py b/release/io/netrender/client.py
index d059387cfcf..a6cfb4e020d 100644
--- a/release/io/netrender/client.py
+++ b/release/io/netrender/client.py
@@ -138,12 +138,12 @@ class NetworkRenderEngine(bpy.types.RenderEngine):
print("UNKNOWN OPERATION MODE")
def render_master(self, scene):
- server_address = (scene.network_render.server_address, scene.network_render.server_port)
- httpd = master.RenderMasterServer(server_address, master.RenderHandler, scene.network_render.path)
- httpd.timeout = 1
- httpd.stats = self.update_stats
- while not self.test_break():
- httpd.handle_request()
+ netsettings = scene.network_render
+
+ address = "" if netsettings.server_address == "[default]" else netsettings.server_address
+
+ master.runMaster((address, netsettings.server_port), netsettings.server_broadcast, netsettings.path, self.update_stats, self.test_break)
+
def render_slave(self, scene):
slave.render_slave(self, scene)
@@ -152,6 +152,7 @@ class NetworkRenderEngine(bpy.types.RenderEngine):
netsettings = scene.network_render
self.update_stats("", "Network render client initiation")
+
conn = clientConnection(scene)
if conn:
diff --git a/release/io/netrender/master.py b/release/io/netrender/master.py
index 78e9243bc9d..13e8b399d6c 100644
--- a/release/io/netrender/master.py
+++ b/release/io/netrender/master.py
@@ -1,5 +1,5 @@
import sys, os
-import http, http.client, http.server, urllib
+import http, http.client, http.server, urllib, socket
import subprocess, shutil, time, hashlib
from netrender.utils import *
@@ -529,7 +529,7 @@ class RenderHandler(http.server.BaseHTTPRequestHandler):
job_frame = int(self.headers['job-frame'])
buf = self.rfile.read(length)
- f = open(job.save_path + "%04d" % job_frame + ".log", 'wb')
+ f = open(job.save_path + "%04d" % job_frame + ".log", 'ab')
f.write(buf)
f.close()
@@ -613,3 +613,23 @@ class RenderMasterServer(http.server.HTTPServer):
return job, job.getFrames()
return None, None
+
+def runMaster(address, broadcast, path, update_stats, test_break):
+ httpd = RenderMasterServer(address, RenderHandler, path)
+ httpd.timeout = 1
+ httpd.stats = update_stats
+
+ if broadcast:
+ s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
+ s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
+
+ start_time = time.time()
+
+ while not test_break():
+ httpd.handle_request()
+
+ if broadcast:
+ if time.time() - start_time >= 10: # need constant here
+ print("broadcasting address")
+ s.sendto(bytes("%s:%i" % address, encoding='utf8'), 0, ('<broadcast>',address[1]))
+ start_time = time.time()
diff --git a/release/io/netrender/operators.py b/release/io/netrender/operators.py
index 655afa6631f..928c2b9efaf 100644
--- a/release/io/netrender/operators.py
+++ b/release/io/netrender/operators.py
@@ -1,6 +1,6 @@
import bpy
import sys, os
-import http, http.client, http.server, urllib
+import http, http.client, http.server, urllib, socket
from netrender.utils import *
import netrender.client as client
@@ -316,4 +316,41 @@ class netclientdownload(bpy.types.Operator):
return ('FINISHED',)
def invoke(self, context, event):
- return self.execute(context) \ No newline at end of file
+ return self.execute(context)
+
+@rnaOperator
+class netclientscan(bpy.types.Operator):
+ '''Operator documentation text, will be used for the operator tooltip and python docs.'''
+ __idname__ = "render.netclientscan"
+ __label__ = "Net Render Client Scan"
+
+ # List of operator properties, the attributes will be assigned
+ # to the class instance from the operator settings before calling.
+
+ __props__ = []
+
+ def poll(self, context):
+ return True
+
+ def execute(self, context):
+ netsettings = context.scene.network_render
+
+ s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
+ s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
+ s.settimeout(30)
+
+ s.bind(('', netsettings.server_port))
+
+ try:
+ buf, address = s.recvfrom(128)
+
+ print("received:", buf)
+
+ netsettings.server_address = address[0]
+ except socket.timeout:
+ print("no server info")
+
+ return ('FINISHED',)
+
+ def invoke(self, context, event):
+ return self.execute(context)
diff --git a/release/io/netrender/slave.py b/release/io/netrender/slave.py
index c12c846231d..1dcb608931e 100644
--- a/release/io/netrender/slave.py
+++ b/release/io/netrender/slave.py
@@ -105,6 +105,8 @@ def render_slave(engine, scene):
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)
+ headers = {"job-id":job.id, "slave-id":slave_id}
+
cancelled = False
stdout = bytes()
run_t = time.time()
@@ -113,10 +115,18 @@ def render_slave(engine, scene):
current_t = time.time()
cancelled = engine.test_break()
if current_t - run_t > CANCEL_POLL_SPEED:
+
+ # update logs. Eventually, it should support one log file for many frames
+ for frame in job.frames:
+ headers["job-frame"] = str(frame.number)
+ conn.request("PUT", "log", stdout, headers=headers)
+ response = conn.getresponse()
+
+ stdout = bytes()
+
+ run_t = current_t
if testCancel(conn, job.id):
cancelled = True
- else:
- run_t = current_t
if cancelled:
# kill process if needed
@@ -132,6 +142,13 @@ def render_slave(engine, scene):
print("status", status)
+ # flush the rest of the logs
+ if stdout:
+ for frame in job.frames:
+ headers["job-frame"] = str(frame.number)
+ conn.request("PUT", "log", stdout, headers=headers)
+ response = conn.getresponse()
+
headers = {"job-id":job.id, "slave-id":slave_id, "job-time":str(avg_t)}
if status == 0: # non zero status is error
@@ -150,12 +167,6 @@ def render_slave(engine, scene):
# send error result back to server
conn.request("PUT", "render", headers=headers)
response = conn.getresponse()
-
- for frame in job.frames:
- headers["job-frame"] = str(frame.number)
- # send log in any case
- conn.request("PUT", "log", stdout, headers=headers)
- response = conn.getresponse()
else:
if timeout < MAX_TIMEOUT:
timeout += INCREMENT_TIMEOUT
diff --git a/release/io/netrender/ui.py b/release/io/netrender/ui.py
index eee95bdac19..df2b6288fb0 100644
--- a/release/io/netrender/ui.py
+++ b/release/io/netrender/ui.py
@@ -48,17 +48,24 @@ class SCENE_PT_network_settings(RenderButtonsPanel):
col = split.column()
- col.itemO("render.netclientanim", icon='ICON_RENDER_ANIMATION', text="Animaton on network")
+ if scene.network_render.mode == "RENDER_CLIENT":
+ col.itemO("render.netclientanim", icon='ICON_RENDER_ANIMATION', text="Animaton on network")
+
col.itemR(scene.network_render, "mode")
+ col.itemR(scene.network_render, "path")
col.itemR(scene.network_render, "server_address")
col.itemR(scene.network_render, "server_port")
- col.itemR(scene.network_render, "path")
+
+ if scene.network_render.mode == "RENDER_MASTER":
+ col.itemR(scene.network_render, "server_broadcast")
+ else:
+ col.itemO("render.netclientscan", icon="ICON_FILE_REFRESH", text="")
if scene.network_render.mode == "RENDER_CLIENT":
- col.itemR(scene.network_render, "chunks")
- col.itemR(scene.network_render, "priority")
- col.itemR(scene.network_render, "job_name")
col.itemO("render.netclientsend", text="send job to server")
+ col.itemR(scene.network_render, "job_name")
+ col.itemR(scene.network_render, "priority")
+ col.itemR(scene.network_render, "chunks")
@rnaType
class SCENE_PT_network_slaves(RenderButtonsPanel):
@@ -192,7 +199,7 @@ NetRenderSettings.StringProperty( attr="server_address",
name="Server address",
description="IP or name of the master render server",
maxlen = 128,
- default = "127.0.0.1")
+ default = "[default]")
NetRenderSettings.IntProperty( attr="server_port",
name="Server port",
@@ -201,6 +208,11 @@ NetRenderSettings.IntProperty( attr="server_port",
min=1,
max=65535)
+NetRenderSettings.BoolProperty( attr="server_broadcast",
+ name="Broadcast server address",
+ description="broadcast server address on local network",
+ default = True)
+
NetRenderSettings.StringProperty( attr="path",
name="Path",
description="Path for temporary files",
diff --git a/release/io/netrender/utils.py b/release/io/netrender/utils.py
index db6646e6916..72a29472748 100644
--- a/release/io/netrender/utils.py
+++ b/release/io/netrender/utils.py
@@ -22,9 +22,12 @@ def rnaOperator(rna_op):
return rna_op
def clientConnection(scene):
- netrender = scene.network_render
+ netsettings = scene.network_render
- conn = http.client.HTTPConnection(netrender.server_address, netrender.server_port)
+ if netsettings.server_address == "[default]":
+ bpy.ops.render.netclientscan()
+
+ conn = http.client.HTTPConnection(netsettings.server_address, netsettings.server_port)
if clientVerifyVersion(conn):
return conn