[Bf-extensions-cvs] SVN commit: /data/svn/bf-extensions [2903] trunk/py/scripts/addons/ netrender: netrender

Martin Poirier theeth at yahoo.com
Sun Jan 15 20:51:07 CET 2012


Revision: 2903
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-extensions&revision=2903
Author:   theeth
Date:     2012-01-15 19:51:01 +0000 (Sun, 15 Jan 2012)
Log Message:
-----------
netrender
use threading for interprocess communication. Don't stall slave communication when rendering/baking process output blocks. This enables running slow baking and rendering jobs correctly without the slave disconnecting from the master. It also makes slaves much more responsive to cancelling jobs on the master.

add save on job option (default false) to save the current file before sending a rendering blender job.

Modified Paths:
--------------
    trunk/py/scripts/addons/netrender/client.py
    trunk/py/scripts/addons/netrender/slave.py
    trunk/py/scripts/addons/netrender/ui.py

Modified: trunk/py/scripts/addons/netrender/client.py
===================================================================
--- trunk/py/scripts/addons/netrender/client.py	2012-01-15 16:10:23 UTC (rev 2902)
+++ trunk/py/scripts/addons/netrender/client.py	2012-01-15 19:51:01 UTC (rev 2903)
@@ -259,10 +259,13 @@
         job.addFrame(scene.frame_current)
 
     filename = bpy.data.filepath
-    
+
     if not os.path.exists(filename):
         raise RuntimeError("Current file path not defined\nSave your file before sending a job")
     
+    if netsettings.save_before_job:
+        bpy.ops.wm.save_mainfile(filepath=filename, check_existing=False)
+
     job.addFile(filename)
 
     job_name = netsettings.job_name

Modified: trunk/py/scripts/addons/netrender/slave.py
===================================================================
--- trunk/py/scripts/addons/netrender/slave.py	2012-01-15 16:10:23 UTC (rev 2902)
+++ trunk/py/scripts/addons/netrender/slave.py	2012-01-15 19:51:01 UTC (rev 2903)
@@ -18,7 +18,7 @@
 
 import sys, os, platform, shutil
 import http, http.client, http.server
-import subprocess, time
+import subprocess, time, threading
 import json
 
 import bpy
@@ -239,24 +239,46 @@
                 
                 results = []
 
-                cancelled = False
-                stdout = bytes()
-                run_t = time.time()
                 line = ""
-                while not cancelled and process.poll() is None:
-                    stdout += process.stdout.read(1024)
-                    current_t = time.time()
-                    cancelled = engine.test_break()
-                    if current_t - run_t > CANCEL_POLL_SPEED:
+                
+                class ProcessData:
+                    def __init__(self):
+                        self.lock = threading.Lock()
+                        self.stdout = bytes()
+                        self.cancelled = False
+                        self.start_time = time.time()
+                        self.last_time = time.time()
+                        
+                data = ProcessData()
+                
+                def run_process(process, data):
+                    while not data.cancelled and process.poll() is None:
+                        buf = process.stdout.read(1024)
+                        
+                        data.lock.acquire()
+                        data.stdout += buf
+                        data.lock.release()
+                        
+                process_thread = threading.Thread(target=run_process, args=(process, data))
+                
+                process_thread.start()
+                
+                while not data.cancelled and process_thread.is_alive():
+                    time.sleep(CANCEL_POLL_SPEED / 2)
+                    current_time = time.time()
+                    data.cancelled = engine.test_break()
+                    if current_time - data.last_time > CANCEL_POLL_SPEED:
 
+                        data.lock.acquire()
+
                         # update logs if needed
-                        if stdout:
+                        if data.stdout:
                             # (only need to update on one frame, they are linked
                             with ConnectionContext():
-                                conn.request("PUT", logURL(job.id, first_frame), stdout, headers=headers)
+                                conn.request("PUT", logURL(job.id, first_frame), data.stdout, headers=headers)
                             responseStatus(conn)
                             
-                            stdout_text = str(stdout, encoding='utf8')
+                            stdout_text = str(data.stdout, encoding='utf8')
                             
                             # Also output on console
                             if netsettings.use_slave_output_log:
@@ -268,20 +290,25 @@
                             if job.subtype == netrender.model.JOB_SUB_BAKING:
                                 results.extend(netrender.baking.resultsFromOuput(lines))
 
-                            stdout = bytes()
+                            data.stdout = bytes()
+                            
+                        data.lock.release()
 
-                        run_t = current_t
+                        data.last_time = current_time
                         if testCancel(conn, job.id, first_frame):
                             engine.update_stats("", "Job canceled by Master")
-                            cancelled = True
+                            data.cancelled = True
+                
+                process_thread.join()
+                del process_thread
 
                 if job.type == netrender.model.JOB_BLENDER:
                     netrender.repath.reset(job)
 
                 # read leftovers if needed
-                stdout += process.stdout.read()
+                data.stdout += process.stdout.read()
 
-                if cancelled:
+                if data.cancelled:
                     # kill process if needed
                     if process.poll() is None:
                         try:
@@ -291,8 +318,8 @@
                     continue # to next frame
 
                 # flush the rest of the logs
-                if stdout:
-                    stdout_text = str(stdout, encoding='utf8')
+                if data.stdout:
+                    stdout_text = str(data.stdout, encoding='utf8')
                     
                     # Also output on console
                     if netsettings.use_slave_output_log:
@@ -305,12 +332,12 @@
 
                     # (only need to update on one frame, they are linked
                     with ConnectionContext():
-                        conn.request("PUT", logURL(job.id, first_frame), stdout, headers=headers)
+                        conn.request("PUT", logURL(job.id, first_frame), data.stdout, headers=headers)
                     
                     if responseStatus(conn) == http.client.NO_CONTENT:
                         continue
 
-                total_t = time.time() - start_t
+                total_t = time.time() - data.start_time
 
                 avg_t = total_t / len(job.frames)
 

Modified: trunk/py/scripts/addons/netrender/ui.py
===================================================================
--- trunk/py/scripts/addons/netrender/ui.py	2012-01-15 16:10:23 UTC (rev 2902)
+++ trunk/py/scripts/addons/netrender/ui.py	2012-01-15 19:51:01 UTC (rev 2903)
@@ -221,6 +221,11 @@
         row = layout.row()
         row.prop(netsettings, "priority")
         row.prop(netsettings, "chunks")
+        
+        if netsettings.job_type == "JOB_BLENDER":
+            layout.prop(netsettings, "save_before_job")
+            
+        
 
 class RENDER_PT_network_job_vcs(NetRenderButtonsPanel, bpy.types.Panel):
     bl_label = "VCS Job Settings"
@@ -491,6 +496,11 @@
                         maxlen = 128,
                         default = "")
         
+        NetRenderSettings.save_before_job = BoolProperty(
+                        name="Save Before Job",
+                        description="Save current file before sending a job",
+                        default = False)
+
         NetRenderSettings.chunks = IntProperty(
                         name="Chunks",
                         description="Number of frame to dispatch to each slave in one chunk",



More information about the Bf-extensions-cvs mailing list