Revision: 23261
          
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=23261
Author:   theeth
Date:     2009-09-15 21:53:18 +0200 (Tue, 15 Sep 2009)

Log Message:
-----------
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.

Modified Paths:
--------------
    trunk/blender/release/io/netrender/client.py
    trunk/blender/release/io/netrender/master.py
    trunk/blender/release/io/netrender/operators.py
    trunk/blender/release/io/netrender/slave.py
    trunk/blender/release/io/netrender/ui.py
    trunk/blender/release/io/netrender/utils.py

Modified: trunk/blender/release/io/netrender/client.py
===================================================================
--- trunk/blender/release/io/netrender/client.py        2009-09-15 19:36:10 UTC 
(rev 23260)
+++ trunk/blender/release/io/netrender/client.py        2009-09-15 19:53:18 UTC 
(rev 23261)
@@ -138,13 +138,13 @@
                        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 @@
                netsettings = scene.network_render
                self.update_stats("", "Network render client initiation")
                
+               
                conn = clientConnection(scene)
                
                if conn:

Modified: trunk/blender/release/io/netrender/master.py
===================================================================
--- trunk/blender/release/io/netrender/master.py        2009-09-15 19:36:10 UTC 
(rev 23260)
+++ trunk/blender/release/io/netrender/master.py        2009-09-15 19:53:18 UTC 
(rev 23261)
@@ -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 @@
                                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 @@
                                        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()

Modified: trunk/blender/release/io/netrender/operators.py
===================================================================
--- trunk/blender/release/io/netrender/operators.py     2009-09-15 19:36:10 UTC 
(rev 23260)
+++ trunk/blender/release/io/netrender/operators.py     2009-09-15 19:53:18 UTC 
(rev 23261)
@@ -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 @@
                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)

Modified: trunk/blender/release/io/netrender/slave.py
===================================================================
--- trunk/blender/release/io/netrender/slave.py 2009-09-15 19:36:10 UTC (rev 
23260)
+++ trunk/blender/release/io/netrender/slave.py 2009-09-15 19:53:18 UTC (rev 
23261)
@@ -105,6 +105,8 @@
                                
                                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 @@
                                        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 @@
                                
                                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 @@
                                                # 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

Modified: trunk/blender/release/io/netrender/ui.py
===================================================================
--- trunk/blender/release/io/netrender/ui.py    2009-09-15 19:36:10 UTC (rev 
23260)
+++ trunk/blender/release/io/netrender/ui.py    2009-09-15 19:53:18 UTC (rev 
23261)
@@ -48,17 +48,24 @@
                
                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.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")
-                       col.itemR(scene.network_render, "priority")
-                       col.itemR(scene.network_render, "job_name")
-                       col.itemO("render.netclientsend", text="send job to 
server")
 
 @rnaType
 class SCENE_PT_network_slaves(RenderButtonsPanel):
@@ -192,7 +199,7 @@
                                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 @@
                                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",

Modified: trunk/blender/release/io/netrender/utils.py
===================================================================
--- trunk/blender/release/io/netrender/utils.py 2009-09-15 19:36:10 UTC (rev 
23260)
+++ trunk/blender/release/io/netrender/utils.py 2009-09-15 19:53:18 UTC (rev 
23261)
@@ -22,10 +22,13 @@
        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
                else:


_______________________________________________
Bf-blender-cvs mailing list
Bf-blender-cvs@blender.org
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to