def killContext(self, contextName): contextKey = self.contextKeys[contextName] LOG("Killing context '" + contextName + "':" + repr(contextKey), level = LOG_PROC ) self.__ctxIFC.disconnect( contextKey, eoc = False ) ProcessManager.instance().killProcess( contextName ) LOG("Context killed", level = LOG_PROC ) self.contextStatus[contextName] = LstMessages.DATA_CTX_AVAILABLE self.clearContext(contextName) # Now kill all associated executors try: registry = ProcessRegistry("CTX_" + contextName, True) executors = registry.getProcesses() for ex in executors: LOG("Killing child executor " + str(ex)) ProcessManager.instance().killPID(ex.getPID()) registry.removeProcess(ex.getName()) except BaseException,ex: LOG("Unable to kill associated executors in context " + contextName + ": " + str(ex), LOG_ERROR )
def killContext(self, contextName): contextKey = self.contextKeys[contextName] LOG("Killing context '" + contextName + "':" + repr(contextKey), level=LOG_PROC) self.__ctxIFC.disconnect(contextKey, eoc=False) ProcessManager.instance().killProcess(contextName) LOG("Context killed", level=LOG_PROC) self.contextStatus[contextName] = LstMessages.DATA_CTX_AVAILABLE self.clearContext(contextName) # Now kill all associated executors try: registry = ProcessRegistry("CTX_" + contextName, True) executors = registry.getProcesses() for ex in executors: LOG("Killing child executor " + str(ex)) ProcessManager.instance().killPID(ex.getPID()) registry.removeProcess(ex.getName()) except BaseException, ex: LOG( "Unable to kill associated executors in context " + contextName + ": " + str(ex), LOG_ERROR)
class ListenerClass(object): """ Main class of the SPEL Listener entity. Listens at a given port waiting for GUI connections. Manages the SPEL Context processes on GUI requests. """ # Client key list clientKeys = [] # Context list contexts = [] # Holds contextID / key pairs contextKeys = {} # Holds contextID / port pairs contextPorts = {} # Context status (available/running) contextStatus = {} # GUI operations delegate GUI_Operations = None # Synchronization issues buffer = None # IPC context interface __ctxIFC = None # IPC gui interface __guiIFC = None # Client lock __clientLock = None # Context lock __ctxLock = None #=========================================================================== def __init__(self, warmStart=False): self.openContexts = {} self.buffer = Queue(1) self.GUI_Operations = GUIOperations(self) # Obtain the list of available contexts from cfg file self.contexts = Config.instance().getAvailableContexts() # Update the context status map (all available) for ctx in self.contexts: self.contextPorts[ctx] = 0 self.contextStatus[ctx] = LstMessages.DATA_CTX_AVAILABLE self.__ctxIFC = IPCinterfaceServer("LST-CTX") self.__guiIFC = IPCinterfaceServer("LST-GUI") self.__clientLock = thread.allocate_lock() self.__ctxLock = thread.allocate_lock() self.__contextRegistry = ProcessRegistry("LST", warmStart) #=========================================================================== def start(self): # Get the port number from configuration port = Config.instance().getProperty(LISTENER, "ListenerPort") LOG("Listening at port: " + str(port), level = LOG_INIT ) # Setup the GUI io channel LOG("Setting up GUI channel", level = LOG_INIT) self.__guiIFC.connect(999, int(port), self.processGuiMessage, self.processGuiRequest, self.clientConnectionLost) self.__guiIFC.start() # Setup the Context io channel LOG("Setting up CTX channel", level = LOG_INIT) self.__ctxIFC.connect(998,0,self.processCtxMessage, self.processCtxRequest, self.contextConnectionLost) self.__ctxIFC.start() LOG("Ready", level = LOG_INIT ) #Restoring warm context for contextInfo in self.__contextRegistry.getProcesses(): #Only during startup we open contexts in warm mode self.openContext(contextInfo.getName(), None, True) #=========================================================================== def stop(self): LOG("Stopping, closing contexts", level = LOG_PROC ) for contextName in self.contexts: if self.isContextRunning(contextName): self.closeContext(contextName) LOG("Killing remaining processes", level = LOG_PROC ) ProcessManager.instance().killAll() self.__guiIFC.disconnect() self.__ctxIFC.disconnect() LOG("Disconnected", level = LOG_INIT ) #=========================================================================== def clientConnectionLost(self, clientKey): if clientKey in self.clientKeys: LOG("Listener lost connection with client: " + repr(clientKey), LOG_ERROR ) self.clientKeys.remove(clientKey) #=========================================================================== def contextConnectionLost(self, contextKey): # Obtain the corresponding name from the key for key in self.contextKeys: if self.contextKeys[key] == contextKey: contextName = key originalStatus = self.contextStatus[contextName] self.contextStatus[contextName] = LstMessages.DATA_CTX_ERROR if not originalStatus == LstMessages.DATA_CTX_STARTING: LOG("Listener lost connection with starting context " + repr(contextName), LOG_ERROR) else: LOG("Listener lost connection with context " + repr(contextName), LOG_ERROR) self.notifyContextCrash(contextName) self.clearContext(contextName) self.__ctxIFC.disconnect(contextKey, eoc = False) LOG("Context-lost done") #=========================================================================== def contextProcessLost(self, contextName, retCode): if (retCode == 0) and not contextName in self.contextKeys: LOG("Context finished with code 0") return self.contextStatus[contextName] = LstMessages.DATA_CTX_ERROR if contextName in self.contexts: LOG("Listener lost track of context " + repr(contextName), LOG_ERROR) self.notifyContextCrash(contextName) self.clearContext(contextName) if contextName in self.contextKeys: contextKey = self.contextKeys[contextName] self.__ctxIFC.disconnect(contextKey, eoc = False) LOG("Done") #=========================================================================== def processGuiMessage(self, msg): self.__clientLock.acquire() LOG("Received GUI message: " + msg.getId(), level = LOG_COMM) guiKey = int(msg.getKey()) if msg.getId() == LstMessages.MSG_GUI_LOGIN: LOG("Client logged in: " + str(guiKey), level = LOG_PROC) self.clientKeys.append(guiKey) elif msg.getId() == LstMessages.MSG_GUI_LOGOUT: self.clientKeys.remove(guiKey) LOG("Client logged out: " + str(guiKey), level = LOG_PROC) else: LOG("ERROR: unknown message from client: " + str(msg.getId()), LOG_ERROR) self.__clientLock.release() #=========================================================================== def processCtxMessage(self, msg): self.__ctxLock.acquire() LOG("Received Context message: " + msg.getId(), level = LOG_COMM) if msg.getId() == LstMessages.MSG_CONTEXT_OPEN: contextName = msg[LstMessages.FIELD_CTX_NAME] LOG("Context logged in: " + contextName, level = LOG_PROC) contextKey = int(msg.getKey()) ctxPort = msg[LstMessages.FIELD_CTX_PORT] self.contextPorts[contextName] = ctxPort self.contextStatus[contextName] = LstMessages.DATA_CTX_RUNNING self.contextKeys[contextName] = contextKey self.buffer.put(ctxPort, True) elif msg.getId() == LstMessages.MSG_CONTEXT_CLOSED: contextName = msg[LstMessages.FIELD_CTX_NAME] contextKey = int(msg.getKey()) LOG("Context logged out: " + contextName + ":" + repr(contextKey), level = LOG_PROC) self.contextStatus[contextName] = LstMessages.DATA_CTX_AVAILABLE self.buffer.put(contextName, True) else: LOG("ERROR: unknown message from context:" + str(msg.getId()), LOG_ERROR) self.__ctxLock.release() #=========================================================================== def processGuiRequest(self, msg): self.__clientLock.acquire() resp = self.GUI_Operations.processRequest(msg) self.__clientLock.release() return resp #=========================================================================== def processCtxRequest(self, msg): self.__ctxLock.acquire() resp = self.createResponse("NONE", msg) self.__ctxLock.release() return resp #=========================================================================== def openContext(self, contextName, clientKey = None, warm = False ): ctxScript = Config.instance().getProperty(LISTENER, "ContextScript") ctxScript = Config.instance().getHome() + os.sep + ctxScript arguments = "-c \"" + Config.instance().filename + "\" -n \"" + contextName + "\"" arguments += " -s " + str(self.__ctxIFC.port) if warm == True: arguments += " -w" pythonBin = os.getenv("PYTHON", "python") ctxScript = pythonBin + " \"" + ctxScript + "\" " + arguments # Set the status as starting (internal) self.contextStatus[contextName] = LstMessages.DATA_CTX_STARTING LOG("Starting context: '" + contextName + "'", level = LOG_PROC ) pid = ProcessManager.instance().startProcess( contextName, ctxScript, self.contextProcessLost ) LOG("Context started with pid " + str(pid), level = LOG_PROC ) LOG("Waiting context port", level = LOG_PROC ) try: ctxPort = self.buffer.get(True,CONTEXT_START_TIMEO) LOG("Context port is " + str(ctxPort), level = LOG_PROC ) # Set the status as started self.contextStatus[contextName] = LstMessages.DATA_CTX_RUNNING self.notifyContextUpdate(contextName,clientKey) self.__contextRegistry.addProcess(pid,contextName) return ctxPort except BaseException,ex: txt = "Failed to open context" reason = "Unable to get context listening port" LOG(txt + ": " + reason, LOG_ERROR) self.killContext(contextName) # Set the status as error self.contextStatus[contextName] = LstMessages.DATA_CTX_ERROR self.notifyContextUpdate(contextName,clientKey,txt,reason) return None
class ListenerClass(object): """ Main class of the SPEL Listener entity. Listens at a given port waiting for GUI connections. Manages the SPEL Context processes on GUI requests. """ # Client key list clientKeys = [] # Context list contexts = [] # Holds contextID / key pairs contextKeys = {} # Holds contextID / port pairs contextPorts = {} # Context status (available/running) contextStatus = {} # GUI operations delegate GUI_Operations = None # Synchronization issues buffer = None # IPC context interface __ctxIFC = None # IPC gui interface __guiIFC = None # Client lock __clientLock = None # Context lock __ctxLock = None #=========================================================================== def __init__(self, warmStart=False): self.openContexts = {} self.buffer = Queue(1) self.GUI_Operations = GUIOperations(self) # Obtain the list of available contexts from cfg file self.contexts = Config.instance().getAvailableContexts() # Update the context status map (all available) for ctx in self.contexts: self.contextPorts[ctx] = 0 self.contextStatus[ctx] = LstMessages.DATA_CTX_AVAILABLE self.__ctxIFC = IPCinterfaceServer("LST-CTX") self.__guiIFC = IPCinterfaceServer("LST-GUI") self.__clientLock = thread.allocate_lock() self.__ctxLock = thread.allocate_lock() self.__contextRegistry = ProcessRegistry("LST", warmStart) #=========================================================================== def start(self): # Get the port number from configuration port = Config.instance().getProperty(LISTENER, "ListenerPort") LOG("Listening at port: " + str(port), level=LOG_INIT) # Setup the GUI io channel LOG("Setting up GUI channel", level=LOG_INIT) self.__guiIFC.connect(999, int(port), self.processGuiMessage, self.processGuiRequest, self.clientConnectionLost) self.__guiIFC.start() # Setup the Context io channel LOG("Setting up CTX channel", level=LOG_INIT) self.__ctxIFC.connect(998, 0, self.processCtxMessage, self.processCtxRequest, self.contextConnectionLost) self.__ctxIFC.start() LOG("Ready", level=LOG_INIT) #Restoring warm context for contextInfo in self.__contextRegistry.getProcesses(): #Only during startup we open contexts in warm mode self.openContext(contextInfo.getName(), None, True) #=========================================================================== def stop(self): LOG("Stopping, closing contexts", level=LOG_PROC) for contextName in self.contexts: if self.isContextRunning(contextName): self.closeContext(contextName) LOG("Killing remaining processes", level=LOG_PROC) ProcessManager.instance().killAll() self.__guiIFC.disconnect() self.__ctxIFC.disconnect() LOG("Disconnected", level=LOG_INIT) #=========================================================================== def clientConnectionLost(self, clientKey): if clientKey in self.clientKeys: LOG("Listener lost connection with client: " + repr(clientKey), LOG_ERROR) self.clientKeys.remove(clientKey) #=========================================================================== def contextConnectionLost(self, contextKey): # Obtain the corresponding name from the key for key in self.contextKeys: if self.contextKeys[key] == contextKey: contextName = key originalStatus = self.contextStatus[contextName] self.contextStatus[contextName] = LstMessages.DATA_CTX_ERROR if not originalStatus == LstMessages.DATA_CTX_STARTING: LOG( "Listener lost connection with starting context " + repr(contextName), LOG_ERROR) else: LOG("Listener lost connection with context " + repr(contextName), LOG_ERROR) self.notifyContextCrash(contextName) self.clearContext(contextName) self.__ctxIFC.disconnect(contextKey, eoc=False) LOG("Context-lost done") #=========================================================================== def contextProcessLost(self, contextName, retCode): if (retCode == 0) and not contextName in self.contextKeys: LOG("Context finished with code 0") return self.contextStatus[contextName] = LstMessages.DATA_CTX_ERROR if contextName in self.contexts: LOG("Listener lost track of context " + repr(contextName), LOG_ERROR) self.notifyContextCrash(contextName) self.clearContext(contextName) if contextName in self.contextKeys: contextKey = self.contextKeys[contextName] self.__ctxIFC.disconnect(contextKey, eoc=False) LOG("Done") #=========================================================================== def processGuiMessage(self, msg): self.__clientLock.acquire() LOG("Received GUI message: " + msg.getId(), level=LOG_COMM) guiKey = int(msg.getKey()) if msg.getId() == LstMessages.MSG_GUI_LOGIN: LOG("Client logged in: " + str(guiKey), level=LOG_PROC) self.clientKeys.append(guiKey) elif msg.getId() == LstMessages.MSG_GUI_LOGOUT: self.clientKeys.remove(guiKey) LOG("Client logged out: " + str(guiKey), level=LOG_PROC) else: LOG("ERROR: unknown message from client: " + str(msg.getId()), LOG_ERROR) self.__clientLock.release() #=========================================================================== def processCtxMessage(self, msg): self.__ctxLock.acquire() LOG("Received Context message: " + msg.getId(), level=LOG_COMM) if msg.getId() == LstMessages.MSG_CONTEXT_OPEN: contextName = msg[LstMessages.FIELD_CTX_NAME] LOG("Context logged in: " + contextName, level=LOG_PROC) contextKey = int(msg.getKey()) ctxPort = msg[LstMessages.FIELD_CTX_PORT] self.contextPorts[contextName] = ctxPort self.contextStatus[contextName] = LstMessages.DATA_CTX_RUNNING self.contextKeys[contextName] = contextKey self.buffer.put(ctxPort, True) elif msg.getId() == LstMessages.MSG_CONTEXT_CLOSED: contextName = msg[LstMessages.FIELD_CTX_NAME] contextKey = int(msg.getKey()) LOG("Context logged out: " + contextName + ":" + repr(contextKey), level=LOG_PROC) self.contextStatus[contextName] = LstMessages.DATA_CTX_AVAILABLE self.buffer.put(contextName, True) else: LOG("ERROR: unknown message from context:" + str(msg.getId()), LOG_ERROR) self.__ctxLock.release() #=========================================================================== def processGuiRequest(self, msg): self.__clientLock.acquire() resp = self.GUI_Operations.processRequest(msg) self.__clientLock.release() return resp #=========================================================================== def processCtxRequest(self, msg): self.__ctxLock.acquire() resp = self.createResponse("NONE", msg) self.__ctxLock.release() return resp #=========================================================================== def openContext(self, contextName, clientKey=None, warm=False): ctxScript = Config.instance().getProperty(LISTENER, "ContextScript") ctxScript = Config.instance().getHome() + os.sep + ctxScript arguments = "-c \"" + Config.instance( ).filename + "\" -n \"" + contextName + "\"" arguments += " -s " + str(self.__ctxIFC.port) if warm == True: arguments += " -w" pythonBin = os.getenv("PYTHON", "python") ctxScript = pythonBin + " \"" + ctxScript + "\" " + arguments # Set the status as starting (internal) self.contextStatus[contextName] = LstMessages.DATA_CTX_STARTING LOG("Starting context: '" + contextName + "'", level=LOG_PROC) pid = ProcessManager.instance().startProcess(contextName, ctxScript, self.contextProcessLost) LOG("Context started with pid " + str(pid), level=LOG_PROC) LOG("Waiting context port", level=LOG_PROC) try: ctxPort = self.buffer.get(True, CONTEXT_START_TIMEO) LOG("Context port is " + str(ctxPort), level=LOG_PROC) # Set the status as started self.contextStatus[contextName] = LstMessages.DATA_CTX_RUNNING self.notifyContextUpdate(contextName, clientKey) self.__contextRegistry.addProcess(pid, contextName) return ctxPort except BaseException, ex: txt = "Failed to open context" reason = "Unable to get context listening port" LOG(txt + ": " + reason, LOG_ERROR) self.killContext(contextName) # Set the status as error self.contextStatus[contextName] = LstMessages.DATA_CTX_ERROR self.notifyContextUpdate(contextName, clientKey, txt, reason) return None