def wrapped(event, process_id, wait=True, exit_on_error=False, *args, **kwargs): process_state = event.pool.context['server'].process_state if process_id in process_state: state = process_state[process_id] if is_running(state): event.failed('%s already running.' % name.capitalize()) return logging.debug('Start process "%s"' % name) process_state[process_id] = { 'status': 'open', 'pid': 0, 'id': process_id, 'name': name, } ret = f(event, process_id, *args, **kwargs) if wait: exit_status = ret.wait() # process already running if exit_status == 2: logging.critical( '%s already running. Shutdown it first.', name.capitalize() ) process_state[process_id] = { 'status': 'error', 'pid': 0, 'message': '%s already running.' % name.capitalize(), } event.failed('%s already running.' % name.capitalize()) if exit_on_error and exit_status != 0: exit(0) return ret
def domain_start( event, name=None, id=None, wait=True, exit_on_error=False, server_host=None, server_port=None ): if id is None: id = uuid.uuid4() # deny run two domains with the same name if False: process_state = event.pool.context['server'].process_state for stt in process_state.values(): if name == stt['name'] and is_running(stt): return event.failed( 'Processes with name "%s" is already running' % (name,) ) do_domain_start( event, str(id), wait=wait, exit_on_error=exit_on_error, server_host=server_host, server_port=server_port, name=name ) return True
def stop_process(event, name=None, id=None): """ If name is not None, than check that state have the same name """ # on the second run pid is already in event.context['id'] pid = event.context.get("id", id) state = None process_state = event.pool.context["server"].process_state def is_proper_name(name, state_name): if not name: return False if "." not in name and "." in state_name and state_name.startswith("%s." % name): return True if name == state_name: return True return False if isinstance(pid, uuid.UUID) or str(pid) in process_state: state = process_state[str(pid)] pid = state["pid"] elif isinstance(pid, int): for stt in process_state.values(): if stt["pid"] == pid or (stt["pid"] == 0 and stt["was_pid"] == pid): state = stt break elif name: rows = [] for stt in process_state.values(): if is_proper_name(name, stt["name"]) and stt["pid"]: state = stt rows.append(stt) pid = state["pid"] if len(rows) > 1: command = "" for row in rows: command += "%s (status: %s)\n" % (row["pid"], row["status"]) return event.failed( 'There are %s processes with name "%s".' " Specify which one to stop:\n%s" % (len(rows), name, command) ) if not state: return event.failed('Process state not found for name="%s", id="%s", cant kill' % (name, pid)) if state["pid"] == 0 and state["was_pid"] != 0: pid = state["was_pid"] # first run of the task if "id" not in event.context: event.context["id"] = state["id"] if not is_running(state): return event.failed("%s already stopped." % name.capitalize()) if not isinstance(pid, int) or not pid: return event.failed("Wrong pid format %s" % repr(pid)) if not is_proper_name(name, state["name"]): return event.failed('Process state name "%s" not equal "%s", cant kill' % (state["name"], name)) if state["status"] not in ["exit", "error", "kill", "clean"]: try: os.kill(pid, signal.SIGTERM) logging.debug("Kill %s", pid) process_state[str(state["id"])] = {"status": "kill"} event.expire(600) event.timeout(1) except OSError: process_state[str(state["id"])] = {"status": "error", "message": "Exit but not properly cleaned", "pid": 0} return if state["status"] == "exit" and state["pid"] == 0 and state["was_pid"] != 0 and pid: try: os.kill(pid, 0) try: os.kill(pid, signal.SIGTERM) logging.debug("Kill hang process %s", pid) event.expire(600) except OSError: process_state[str(state["id"])] = { "status": "error", "message": "Exit but not properly cleaned", "pid": 0, } except OSError: # No process with locked PID pass process_state[str(state["id"])] = {"was_pid": 0} return if state["status"] in ["kill", "clean"]: try: os.kill(pid, 0) except OSError: # No process with locked PID # exception while cleaning if state["status"] == "clean": process_state[str(state["id"])] = { "status": "error", "message": "Exit but not properly cleaned", "pid": 0, } logging.warn("Process with pid %s stopped with errors", pid) else: logging.debug("Successfully stopped process with pid %s", pid) return event.timeout(1)
def stop_process(event, name=None, id=None): """ If name is not None, than check that state have the same name """ # on the second run pid is already in event.context['id'] pid = event.context.get('id', id) state = None process_state = event.pool.context['server'].process_state def is_proper_name(name, state_name): if not name: return False if '.' not in name and '.' in state_name \ and state_name.startswith('%s.' % name): return True if name == state_name: return True return False if isinstance(pid, uuid.UUID) or str(pid) in process_state: state = process_state[str(pid)] pid = state['pid'] elif isinstance(pid, int): for stt in process_state.values(): if stt['pid'] == pid or (stt['pid'] == 0 and stt['was_pid'] == pid): state = stt break elif name: rows = [] for stt in process_state.values(): if is_proper_name(name, stt['name']) and stt['pid']: state = stt rows.append(stt) pid = state['pid'] if len(rows) > 1: command = '' for row in rows: command += '%s (status: %s)\n' % (row['pid'], row['status']) return event.failed( 'There are %s processes with name "%s".' \ ' Specify which one to stop:\n%s' % (len(rows), name, command) ) if not state: return event.failed( 'Process state not found for name="%s", id="%s", cant kill' % (name, pid)) if state['pid'] == 0 and state['was_pid'] != 0: pid = state['was_pid'] # first run of the task if 'id' not in event.context: event.context['id'] = state['id'] if not is_running(state): return event.failed('%s already stopped.' % name.capitalize()) if not isinstance(pid, int) or not pid: return event.failed('Wrong pid format %s' % repr(pid)) if not is_proper_name(name, state['name']): return event.failed( 'Process state name "%s" not equal "%s", cant kill' % ( state['name'], name)) if state['status'] not in ['exit', 'error', 'kill', 'clean']: try: os.kill(pid, signal.SIGTERM) logging.debug('Kill %s', pid) process_state[str(state['id'])] = { 'status': 'kill', } event.expire(600) event.timeout(1) except OSError: process_state[str(state['id'])] = { 'status': 'error', 'message': 'Exit but not properly cleaned', 'pid': 0, } return if state['status'] == 'exit' and state['pid'] == 0 \ and state['was_pid'] != 0 and pid: try: os.kill(pid, 0) try: os.kill(pid, signal.SIGTERM) logging.debug('Kill hang process %s', pid) event.expire(600) except OSError: process_state[str(state['id'])] = { 'status': 'error', 'message': 'Exit but not properly cleaned', 'pid': 0, } except OSError: #No process with locked PID pass process_state[str(state['id'])] = { 'was_pid': 0, } return if state['status'] in ['kill', 'clean']: try: os.kill(pid, 0) except OSError: #No process with locked PID # exception while cleaning if state['status'] == 'clean': process_state[str(state['id'])] = { 'status': 'error', 'message': 'Exit but not properly cleaned', 'pid': 0, } logging.warn( 'Process with pid %s stopped with errors', pid) else: logging.debug( 'Successfully stopped process with pid %s', pid) return event.timeout(1)