Skip to content
Snippets Groups Projects
Select Git revision
  • b76d1102ee37b7467fce92c0a687ff4f1b8fd6d7
  • master default protected
2 results

VirtualAcousticsStarterServer.py

Blame
  • VirtualAcousticsStarterServer.py 8.71 KiB
    import sys, socket, subprocess, time, os
    
    oProcess = None
    
    print( "VirtualAcoustics Starter script - press ctrl+c to quit" )
    
    sHostConfigurationFile = "VirtualAcousticStarterConfig." + socket.gethostname() + ".py"
    sGeneralConfigurationFile = "VirtualAcousticStarterConfig.py"
    sCurrentScriptsDirectory = os.path.dirname( os.path.realpath( sys.argv[0] ) )
    
    if os.path.isfile( sHostConfigurationFile ):
      exec( compile( open( sHostConfigurationFile, "rb" ).read(), sHostConfigurationFile, 'exec' ) )
      print("Using config: " + sHostConfigurationFile)
    elif os.path.isfile( sCurrentScriptsDirectory + "/" + sHostConfigurationFile ):
      exec( compile( open( sCurrentScriptsDirectory + "/" + sHostConfigurationFile, "rb" ).read(), sCurrentScriptsDirectory + "/" + sHostConfigurationFile, 'exec' ) )
      print("Using config: " + sCurrentScriptsDirectory + "/" + sHostConfigurationFile)
    elif os.path.isfile( sGeneralConfigurationFile ):
      exec( compile( open( sGeneralConfigurationFile, "rb" ).read(), sGeneralConfigurationFile, 'exec' ) )
      print("Using config: " + sGeneralConfigurationFile)
    elif os.path.isfile( sCurrentScriptsDirectory + "/" + sGeneralConfigurationFile ):
      exec( compile( open( sCurrentScriptsDirectory + "/" + sGeneralConfigurationFile, "rb" ).read(), sCurrentScriptsDirectory + "/" + sGeneralConfigurationFile, 'exec' ) )
      print("Using config: " + sCurrentScriptsDirectory + "/" + sGeneralConfigurationFile)
    else:
      print( "ERROR: No configuration file found - please create " + sHostConfigurationFile + " or " + sGeneralConfigurationFile )
      sys.exit( 4 )
    
    try:
      tVirtualAcousticVersions
      sLocalIP
      nLocalPort
      nDefaultSleep
    except NameError:
      print( "ERROR: configuration did not define required variables: tVirtualAcousticVersions, sLocalIP, nLocalPort, nDefaultSleep" )
      sys.exit( 5 )
    
    print( "Creating server socket at " + sLocalIP + ":" + str( nLocalPort ) )
    
    oServer = socket.socket()
    if sLocalIP == "":
      sLocalIP = socket.gethostname()
    try:
      oServer.bind( ( sLocalIP, nLocalPort ) )
      oServer.listen( 3 )
    except socket.error:
      print( "Error on binding socket" )
      sys.exit( 1 )
      
    try:
    
      oServer.settimeout( 0.5 )
      while True:
        print( "Waiting for connection..." )
        oConnection = None
        while not oConnection:
          try:
            oConnection, sAddress = oServer.accept()
          except socket.timeout:
            oConnection = None
          except socket.error:
            print( "Error while listening for connection" )
            sys.exit( 2 )
          except (KeyboardInterrupt, SystemExit):
            raise
            
        print( "Connection received from " + sAddress[0] )
        
        if oProcess:
          print( "Closing current VA instance" )
          oProcess.kill()
          oProcess = None
          
        # read variant to start
        try:
          sVariantName = oConnection.recv( 512 )
          if type( sVariantName ) is bytes: 
            sVariantName = sVariantName.decode( 'utf-8' )
          print( "received start request for variant: " + sVariantName )
        except socket.error:
          print( "Error while reading variant" )
          oConnection.close()
        except (KeyboardInterrupt, SystemExit):
          raise
        else:
          try:
            tInstance = tVirtualAcousticVersions[sVariantName]
          except KeyError:
            tInstance = None
            
          if not tInstance:
            print( 'Requested VA Instance "' + sVariantName + '" not available' )
            oConnection.send( b'f' )
            oConnection.close()
          else:
            try:
              sWorkingDir = tInstance["dir"]
            except KeyError:
              sWorkingDir = None
                
            try:
              sFile = tInstance["file"]
              if not os.path.isfile( sFile ):
                if sWorkingDir and os.path.isfile( sWorkingDir + "/" + sFile ):
                  sFile = sWorkingDir + "/" + sFile
                else:
                  print( "ERROR: Invalid config for " + sVariantName + " -- file " + sFile + " does not exist" )
                  oConnection.send( b'n' )            
              elif sWorkingDir == None:
                sWorkingDir = os.path.dirname( sFile )
            except KeyError:
              sFile = None
              print( "ERROR: config for " + sVariantName + " has no valid \"file\" entry" )
              oConnection.send( b'i' )
              oConnection.close()
              
            if sFile:
              sCommand = sFile
              try:
                sParams = tInstance["params"]
                sCommand = sCommand + ' ' + sParams
              except KeyError:
                sParams = None
    
              try:
                nSleep = tInstance["sleep"]
              except KeyError:
                nSleep = nDefaultSleep            
                
              # start instance
              print( 'executing "' + sCommand + '"' )
              
              oProcess = subprocess.Popen( sCommand, cwd = sWorkingDir, creationflags=subprocess.CREATE_NEW_PROCESS_GROUP )
              
              # wait for requested duration before sending the go signal
              time.sleep( nSleep )
              
              if oProcess.poll() != None:
                print( "VA Process died - sending abort token" )
                oConnection.send( b'a' )
              else:
              
                print( "sending go token" )
                oConnection.send( b'g' )
                
                #wait until quit command arrives, or the connection closes
                bContinue = True
                oConnection.settimeout( 1.0 )
                while bContinue:
                  try:
                    sResult = oConnection.recv( 128 )
                    
                    if sResult != '':
                      #check whether we are about to reveive a file
                      sMessage = sResult.decode("utf-8")
                      if sMessage.startswith("file"):
                        aMessageParts = sMessage.split(":")
                        iBytesToReceive = int(aMessageParts[2])
                        Path, Filename = os.path.split(aMessageParts[1])
                        ProjectName = aMessageParts[3]
                        Fullpath = os.path.join(sCurrentScriptsDirectory, "..", "tmp", ProjectName, Path, "")
                        print("Should receive file: "+Filename+" in path "+Fullpath+ " with "+str(iBytesToReceive)+" bytes")
    
                        #check whether the file with this exact size already exists
                        if os.path.isfile(Fullpath+Filename) and os.stat(Fullpath+Filename).st_size==iBytesToReceive:
                          oConnection.send( b'exists' )
                          print("File already exists with this size, so no need for resending")
    
                        else: #file need to be received
                          #create dir if it does not exist
                          if not os.path.exists(Fullpath):
                            os.makedirs(Fullpath)
    
                          #send acceptance
                          oConnection.send( b'ack' ) 
                          #print("Send ack")
    
                          #receive file
                          iBytesReceived = 0
                          with open(Fullpath+Filename, "wb") as f:
                            bReceivingFile = True
                            while bReceivingFile:
                              # read 1024 bytes from the socket (receive)
                              bytes_read = oConnection.recv(1024)
                              #print("Read 1024 bytes")
                              if not bytes_read:    
                                # nothing is received
                                # file transmitting is done
                                bReceivingFile = False
                              else:
                                # write to the file the bytes we just received
                                f.write(bytes_read)
                                iBytesReceived += len(bytes_read)
                              if iBytesReceived == iBytesToReceive:
                                bReceivingFile = False
                            f.close()
    
                          #check whether received file seems ok  
                          if iBytesReceived == iBytesToReceive:
                            oConnection.send( b'ack' ) #send acceptance
                            print("File received successfully")
                          else:
                            oConnection.send( b'fail' ) #send failure
                            print("File receive failed")
                      else: #NOT sMessage.startswith("file")      
                        print( "Received quit event: "+sMessage )
                        bContinue = False
                        
                  except socket.timeout:
                    bContinue = True # timeouts are okay
                  except socket.error:
                    print( "Connection terminated unexpectedly" )
                    bContinue = False
                  except (KeyboardInterrupt, SystemExit):
                    raise
    
              # kill VA instance
              print( "Closing VA instance" )
              oProcess.terminate()
              time.sleep( 1 )
              oProcess.kill()
              oProcess = None
            
    except KeyboardInterrupt:
      print( "Caught keyboard interrupt, quitting" )
      
    
    oServer.close()