Skip to content
Snippets Groups Projects
Commit 3458b199 authored by Philipp Schäfer's avatar Philipp Schäfer
Browse files

Launcher script: refactored code significantly (WIP)

- KeyboardInterrupts do not seem to be raised currently
- other functionality should not have changed
- still requires another independent test
parent 1b96d401
No related branches found
No related tags found
No related merge requests found
......@@ -12,6 +12,7 @@ class ErrorCodes(Enum):
ERROR_MISSING_VA_INI = 5
ERROR_INVALID_REPRODUCTION_ID = 6
ERROR_INCOMPLETE_VA_INI = 7
ERROR_UNDEFINED_LAUNCHER_STATE = 8
# Class representing the VA-Launcher config (.json) file
class LauncherConfig:
......@@ -51,6 +52,7 @@ class VAComposedIniParser:
def link_renderer_ini(self):
if not self.sRendererIniPath:
print("No renderer ini-file sent by client, using default one.")
self.sRendererIniPath = "VARenderer.Default.ini"
sMainInifile = self.get_main_inifile()
......@@ -103,6 +105,8 @@ class VirtualAcousticsLauncher:
self.oLauncherServerSocket = None
self.oLauncherConnection = None
self.sCurrentScriptsDirectory = os.path.dirname( os.path.realpath( sys.argv[0] ) )
self.sVAServerID = None
self.sVAServerDir = None
self.start()
......@@ -111,7 +115,7 @@ class VirtualAcousticsLauncher:
print( "VirtualAcoustics Starter script - press ctrl+c to quit" )
self.read_config()
self.open_server_socket()
self.run()
self.main_loop()
#Reads the launcher config and initializes all respective class parameters
......@@ -153,17 +157,48 @@ class VirtualAcousticsLauncher:
sys.exit( ErrorCodes.ERROR_BINDING_SOCKET )
self.oLauncherServerSocket.settimeout( 1.0 )
#Actually starts the launcher listening for VAServer start requests
def run(self):
def _reset_connection(self):
if self.oLauncherConnection:
self.oLauncherConnection.close()
self.oLauncherConnection = None
self.sVAServerDir = None
self.sVAServerID = None
def _close_va_and_reset_connection(self):
if self.oVAProcess:
print( "Closing VA instance" )
self.oVAProcess.terminate()
time.sleep( 1 )
self.oVAProcess.kill()
self.oVAProcess = None
self._reset_connection()
def main_loop(self):
try:
#TODO-PSC: Receive file and name from client
self.vaIniParser.sRendererIniPath = None
self.vaIniParser.prepare_inis()
while True:
print( "Waiting for launcher connection..." )
if not self.oLauncherConnection:
self.wait_for_connection()
self.oLauncherConnection = None
elif self.sVAServerDir and not self.oVAProcess:
self.start_va_server()
elif self.oVAProcess:
self.listen_for_requests()
else:
print("ERROR: Undefined state launcher state leading to infinite loop")
sys.exit( ErrorCodes.ERROR_UNDEFINED_LAUNCHER_STATE )
except KeyboardInterrupt:
print( "Caught keyboard interrupt, quitting" )
self._reset_connection()
def wait_for_connection(self):
print( "Waiting for launcher connection..." )
while not self.oLauncherConnection:
try:
self.oLauncherConnection, sAddress = self.oLauncherServerSocket.accept()
......@@ -182,15 +217,7 @@ class VirtualAcousticsLauncher:
self.oVAProcess.kill()
self.oVAProcess = None
sVAServerDir = self.receive_va_server_id()
if not sVAServerDir:
continue
self.start_va_server(sVAServerDir)
except KeyboardInterrupt:
print( "Caught keyboard interrupt, quitting" )
self.oLauncherServerSocket.close()
self.receive_va_server_id()
#Checks for a message containing the ID of the VAServer instance to be started and returns the respective VAServer directory
......@@ -202,42 +229,42 @@ class VirtualAcousticsLauncher:
print( "Received launch request for variant: " + self.sVAServerID )
except socket.error:
print( "Error while reading variant" )
self.oLauncherConnection.close()
return None
self._reset_connection()
return False
else:
try:
sVAServerDir = self.oConfig.dVirtualAcousticDirectories[self.sVAServerID]
self.sVAServerDir = self.oConfig.dVirtualAcousticDirectories[self.sVAServerID]
except KeyError:
sVAServerDir = None
self.sVAServerDir = None
if not sVAServerDir:
if not self.sVAServerDir:
print( 'Requested VA Instance "' + self.sVAServerID + '" not available' )
self.oLauncherConnection.send( b'f' ) #answer 'requested version not available
self.oLauncherConnection.close()
return None
self._reset_connection()
return False
return sVAServerDir
return True
#Starts the VAServer from given directory
def start_va_server(self, sVAServerDir):
def start_va_server(self):
# Check for VAServer.exe
sVAExecutableFile = "bin/VAServer.exe"
try:
if not os.path.isfile( sVAExecutableFile ):
if sVAServerDir and os.path.isfile( sVAServerDir + "/" + sVAExecutableFile ):
sVAExecutableFile = sVAServerDir + "/" + sVAExecutableFile
if self.sVAServerDir and os.path.isfile( self.sVAServerDir + "/" + sVAExecutableFile ):
sVAExecutableFile = self.sVAServerDir + "/" + sVAExecutableFile
else:
print( "ERROR: Invalid config for " + self.sVAServerID + " -- file " + sVAExecutableFile + " does not exist" )
self.oLauncherConnection.send( b'n' ) #answer 'binary file cannot be found or invalid'
return
elif sVAServerDir == None:
sVAServerDir = os.path.dirname( sVAExecutableFile ) #TODO-PSC: VAServer should always be started from its main directory, not the "bin" folder
elif self.sVAServerDir == None:
self.sVAServerDir = os.path.dirname( sVAExecutableFile ) #TODO-PSC: VAServer should always be started from its main directory, not the "bin" folder
except KeyError:
sVAExecutableFile = None
print( "ERROR: config for " + self.sVAServerID + " has no valid \"file\" entry" )
self.oLauncherConnection.send( b'i' ) #answer 'invalid file entry in the config'
self.oLauncherConnection.close()
self._reset_connection()
return
if not sVAExecutableFile:
......@@ -252,7 +279,7 @@ class VirtualAcousticsLauncher:
# start instance
print( 'executing "' + sCommand + '"' )
self.oVAProcess = subprocess.Popen( sCommand, cwd = sVAServerDir, creationflags=subprocess.CREATE_NEW_PROCESS_GROUP )
self.oVAProcess = subprocess.Popen( sCommand, cwd = self.sVAServerDir, creationflags=subprocess.CREATE_NEW_PROCESS_GROUP )
# wait for requested duration before sending the go signal
time.sleep( self.oConfig.nDefaultSleep )
......@@ -260,22 +287,12 @@ class VirtualAcousticsLauncher:
if self.oVAProcess.poll() != None:
print( "VA Process died - sending abort token" )
self.oLauncherConnection.send( b'a' ) #answer 'VAServer was aborted
self.oLauncherConnection.close()
self._reset_connection()
return
else:
print( "sending go token" )
self.oLauncherConnection.send( b'g' )#answer 'go, VAServer is correctly started'
self.listen_for_requests()
#if the above terminates a quit request was received:
# kill VA instance
print( "Closing VA instance" )
self.oVAProcess.terminate()
time.sleep( 1 )
self.oVAProcess.kill()
self.oVAProcess = None
#Listens for requests while the VAServer is running
def listen_for_requests(self):
while True:
......@@ -289,6 +306,7 @@ class VirtualAcousticsLauncher:
self.receive_file(sMessage)
else: #NOT sMessage.startswith("file")
print( "Received quit event: "+sMessage )
self._close_va_and_reset_connection()
break
except socket.timeout:
......@@ -300,6 +318,7 @@ class VirtualAcousticsLauncher:
except (KeyboardInterrupt, SystemExit):
raise #re-raise for higher instance to catch
def receive_file(self, sMessage):
aMessageParts = sMessage.split(":")
iBytesToReceive = int(aMessageParts[2])
......@@ -349,9 +368,8 @@ class VirtualAcousticsLauncher:
print("File receive failed")
#create an instance of the class
oLauncher = VirtualAcousticsLauncher()
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment