def getAnswer( self, question ): # send the question to a remote server and get an answer back # create a TCP socket sock = socket.socket( socket.AF_INET, socket.SOCK_STREAM ) try: # connect to the server logger.info( 'connect to %s %s', self.hostname, self.port ) sock.connect( ( self.hostname, self.port ) ) # convert the question to ASCII questionBytes = pickle.dumps( question ) # send the question sock.sendall( questionBytes ) # close the sending half of the connection so the other side # knows we're done sending sock.shutdown( socket.SHUT_WR ) # read the response, an ASCII encoded object answerBytes = sock.recv( Constants.MANYBYTES ) # convert the response to an object answer = pickle.loads( answerBytes ) finally: sock.close( ) return answer
def main (): logger.info ('starting in %s', os.getcwd()) logger.info ('arglist %s', sys.argv) socketServer = RenderTCPServer( ) # socketServer.serverThread.join( ) socketServer.createIdleLoop (5, socketServer.processRenderTasks ) pulseThread = threading.Thread(target = heartbeat, name = "heartbeat", args = (60,)) pulseThread.start()
def __init__( self, port = Constants.PORT, ): MyTCPHandler.TCPserver = self logger.info( 'open socket %r %s', "", port ) self.serverObject = MySocketServer( ( "", port), MyTCPHandler) self.serverThread = threading.Thread( target = runTheServer, name = "server thread", args = ( self.serverObject, ) ) self.serverThread.start( )
def handle( self ): logger.info ("request") try: questionBytes = self.rfile.read( ) question = pickle.loads( questionBytes ) logger.debug(question) answer = question.computeAnswer( self.TCPserver ) answerBytes = pickle.dumps( answer ) self.wfile.write( answerBytes ) except: logger.error( """Exception caught: %s""", traceback.format_exc( ) )
def __init__(self, *arglist, **kwargs): # check for another instance of RenderNodeMain.exe nInstances = len (filter (lambda line: 'RenderNodeMain' in line, subprocess.check_output ('tasklist').split('\n'))) logger.info ("%d RenderNodeMain instances running." % nInstances) if nInstances > 1: logger.info("Blocked RenderNodeMain from running because another" " instance already exists.") sys.exit(1) if nInstances == 0 and not sys.argv[0].endswith('.py'): logger.error("Can't find running RenderNodeMain.") sys.exit(1) TCPServer.__init__(self, *arglist, **kwargs) self.childProcess = None self.childKilled = False self.statusAfterDeath = None # must be a status from MySQLSetup # clean up in case we had an unexpected termination last time around [thisNode] = Hydra_rendernode.fetch ("where host = '%s'" % Utils.myHostName()) if thisNode.task_id: if thisNode.status == PENDING or thisNode.status == OFFLINE: newStatus = OFFLINE else: newStatus = IDLE unstick (taskID=thisNode.task_id, newTaskStatus=CRASHED, host=thisNode.host, newHostStatus=newStatus) # update current software version if necessary current_version = sys.argv[0] if thisNode.software_version != current_version: thisNode.software_version = current_version with transaction() as t: thisNode.update(t)
def processRenderTasks(self): [thisNode] = Hydra_rendernode.fetch ("where host = '%s'" % Utils.myHostName( )) logger.info("""Host: %r Status: %r Project: %r Capabilities %r""", thisNode.host, thisNode.status, thisNode.project, thisNode.capabilities) # If this node is not idle, don't try to find a new job if thisNode.status != IDLE: return # otherwise, get a job that's: ## ready to be run and ## has a high enough priority level for this particular node and ## (optionally) is on this node's assigned project queryString = ("where status = '%s' and priority >= %s" % (READY, thisNode.minPriority)) queryString += " and '%s' like requirements" % thisNode.capabilities if thisNode.restrict_to_project: queryString += " and project = '%s'" % thisNode.project orderString = ("order by project = '%s' desc, priority desc, length(requirements) desc, id asc" % thisNode.project) with transaction() as t: render_tasks = Hydra_rendertask.fetch ( queryString, limit=1, order=orderString, explicitTransaction=t) if not render_tasks: return render_task = render_tasks[0] # create log for this task and update task entry in the database if not os.path.isdir( RENDERLOGDIR ): os.makedirs( RENDERLOGDIR ) render_task.logFile = os.path.join(RENDERLOGDIR, '%010d.log.txt' % render_task.id ) render_task.status = STARTED render_task.host = thisNode.host thisNode.status = STARTED thisNode.task_id = render_task.id render_task.startTime = datetime.datetime.now() render_task.update(t) thisNode.update(t) logger.debug ('working on render task %s', render_task.id) log = file(render_task.logFile, 'w') try: log.write('Hydra log file %s on %s\n' % ( render_task.logFile, render_task.host ) ) log.write('RenderNodeMain is %s\n' % sys.argv) log.write ("Initial drive mappings (net use):\n\n") flushOut(log) subprocess.call("net use", stdout = log, stderr = subprocess.STDOUT) if mapDrive ('w:', r'\\oscar.cpc.local\px3'): log.write("Found w:, assuming it's correct.\n") else: log.write("Attempted to map w:\n") flushOut(log) subprocess.call("net use", stdout = log, stderr = subprocess.STDOUT) flushOut(log) log.write('Command: %s\n\n' % ( render_task.command ) ) flushOut(log) # run the job and keep track of the process self.childProcess = subprocess.Popen( eval( render_task.command ), stdout = log, stderr = subprocess.STDOUT ) logger.debug('started PID %s to do task %s', self.childProcess.pid, render_task.id) # wait until the job is finished or terminated render_task.exitCode = self.childProcess.wait() log.write('\nProcess exited with code %d\n' % render_task.exitCode) return RenderAnswer( ) except Exception, e: traceback.print_exc( e, log ) raise
def runTheServer( serverObject ): logger.info ("off to the races") serverObject.serve_forever( )