Skip to content
Snippets Groups Projects
master.py 44.1 KiB
Newer Older
  • Learn to ignore specific revisions
  •             self.jobs_map[job.id] = job
                self.job_id = max(self.job_id, int(job.id))
    
            self.slaves = slaves
            for slave in self.slaves:
                self.slaves_map[slave.id] = slave
            
            if balancer:
                self.balancer = balancer
            
    
        def nextJobID(self):
            self.job_id += 1
            return str(self.job_id)
    
    
    Martin Poirier's avatar
    Martin Poirier committed
        def addSlave(self, slave_info):
            slave = MRenderSlave(slave_info)
    
            self.slaves.append(slave)
            self.slaves_map[slave.id] = slave
    
            return slave.id
    
        def removeSlave(self, slave):
            self.slaves.remove(slave)
            self.slaves_map.pop(slave.id)
    
        def getSlave(self, slave_id):
            return self.slaves_map.get(slave_id)
    
        def getSeenSlave(self, slave_id):
            slave = self.getSlave(slave_id)
            if slave:
                slave.seen()
    
            return slave
    
        def timeoutSlaves(self):
            removed = []
    
            t = time.time()
    
            for slave in self.slaves:
                if (t - slave.last_seen) / 60 > self.slave_timeout:
                    removed.append(slave)
    
                    if slave.job:
                        for f in slave.job_frames:
    
    Martin Poirier's avatar
    Martin Poirier committed
                            slave.job[f].status = netrender.model.FRAME_ERROR
    
    
            for slave in removed:
                self.removeSlave(slave)
    
        def updateUsage(self):
            blend = 0.5
            for job in self.jobs:
                job.usage *= (1 - blend)
    
            if self.slaves:
                slave_usage = blend / self.countSlaves()
    
                for slave in self.slaves:
                    if slave.job:
                        slave.job.usage += slave_usage
    
    
        def clear(self, clear_files = False):
            removed = self.jobs[:]
    
            for job in removed:
                self.removeJob(job, clear_files)
    
        def balance(self):
            self.balancer.balance(self.jobs)
    
        def getJobs(self):
            return self.jobs
    
    
    Martin Poirier's avatar
    Martin Poirier committed
        def countJobs(self, status = netrender.model.JOB_QUEUED):
    
            total = 0
            for j in self.jobs:
                if j.status == status:
                    total += 1
    
            return total
    
        def countSlaves(self):
            return len(self.slaves)
    
        def removeJob(self, job, clear_files = False):
            self.jobs.remove(job)
            self.jobs_map.pop(job.id)
    
            if clear_files:
                shutil.rmtree(job.save_path)
    
            for slave in self.slaves:
                if slave.job == job:
                    slave.job = None
                    slave.job_frames = []
    
        def addJob(self, job):
            self.jobs.append(job)
            self.jobs_map[job.id] = job
    
            # create job directory
            job.save_path = os.path.join(self.path, "job_" + job.id)
    
    
            job.save()
    
        def getJobID(self, id):
            return self.jobs_map.get(id)
    
        def __iter__(self):
            for job in self.jobs:
                yield job
    
    
    Martin Poirier's avatar
    Martin Poirier committed
        def newDispatch(self, slave):
    
            if self.jobs:
                for job in self.jobs:
    
    Martin Poirier's avatar
    Martin Poirier committed
                    if (
                        not self.balancer.applyExceptions(job)      # No exceptions
                        and slave.id not in job.blacklist           # slave is not blacklisted
                        and (not slave.tags or job.tags.issubset(slave.tags))  # slave doesn't use tags or slave has all job tags
                             ):
                        
    
                        return job, job.getFrames()
    
            return None, None
    
    def clearMaster(path):
        shutil.rmtree(path)
    
    
    Martin Poirier's avatar
    Martin Poirier committed
    def createMaster(address, clear, force, path):
    
        filepath = os.path.join(path, "blender_master.data")
    
        if not clear and os.path.exists(filepath):
            print("loading saved master:", filepath)
            with open(filepath, 'rb') as f:
                path, jobs, slaves = pickle.load(f)
                
    
    Martin Poirier's avatar
    Martin Poirier committed
                httpd = RenderMasterServer(address, RenderHandler, path, force=force, subdir=False)
    
                httpd.restore(jobs, slaves)
                
                return httpd
    
    
    Martin Poirier's avatar
    Martin Poirier committed
        return RenderMasterServer(address, RenderHandler, path, force=force)
    
    
    def saveMaster(path, httpd):
        filepath = os.path.join(path, "blender_master.data")
        
        with open(filepath, 'wb') as f:
            pickle.dump((httpd.path, httpd.jobs, httpd.slaves), f, pickle.HIGHEST_PROTOCOL)
    
    
    def runMaster(address, broadcast, clear, force, path, update_stats, test_break,use_ssl=False,cert_path="",key_path=""):
    
    Martin Poirier's avatar
    Martin Poirier committed
        httpd = createMaster(address, clear, force, path)
    
        if use_ssl:
            import ssl
            httpd.socket=ssl.wrap_socket(httpd.socket,certfile=cert_path,server_side=True,keyfile=key_path,ciphers="ALL",ssl_version=ssl.PROTOCOL_SSLv3)
    
        if broadcast:
            s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
            s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
    
        while not test_break():
            try:
                httpd.handle_request()
            except select.error:
                pass
    
            if time.time() - start_time >= 2: # need constant here
                httpd.timeoutSlaves()
    
                if broadcast:
                    print("broadcasting address")
                    s.sendto(bytes("%i" % address[1], encoding='utf8'), 0, ('<broadcast>', 8000))
                    start_time = time.time()
    
        httpd.server_close()
        if clear:
            clearMaster(httpd.path)
        else:
            saveMaster(path, httpd)