def serve(self) -> None: """Serve requests, synchronously (no thread or fork).""" try: sock = self.create_listening_socket() if self.timeout is not None: sock.settimeout(self.timeout) try: with open(STATUS_FILE, 'w') as f: json.dump( { 'pid': os.getpid(), 'sockname': sock.getsockname() }, f) f.write('\n') # I like my JSON with trailing newline while True: try: conn, addr = sock.accept() except socket.timeout: print("Exiting due to inactivity.") reset_global_state() sys.exit(0) try: data = receive(conn) except OSError as err: conn.close() # Maybe the client hung up continue resp = {} # type: Dict[str, Any] if 'command' not in data: resp = {'error': "No command found in request"} else: command = data['command'] if not isinstance(command, str): resp = {'error': "Command is not a string"} else: command = data.pop('command') try: resp = self.run_command(command, data) except Exception: # If we are crashing, report the crash to the client tb = traceback.format_exception( *sys.exc_info()) # type: ignore resp = {'error': "Daemon crashed!\n" + "".join(tb)} conn.sendall(json.dumps(resp).encode('utf8')) raise try: conn.sendall(json.dumps(resp).encode('utf8')) except OSError as err: pass # Maybe the client hung up conn.close() if command == 'stop': sock.close() reset_global_state() sys.exit(0) finally: os.unlink(STATUS_FILE) finally: shutil.rmtree(self.sock_directory) exc_info = sys.exc_info() if exc_info[0] and exc_info[0] is not SystemExit: traceback.print_exception(*exc_info) # type: ignore
def serve(self) -> None: """Serve requests, synchronously (no thread or fork).""" command = None try: server = IPCServer(CONNECTION_NAME, self.timeout) with open(self.status_file, 'w') as f: json.dump( { 'pid': os.getpid(), 'connection_name': server.connection_name }, f) f.write('\n') # I like my JSON with a trailing newline while True: with server: data = receive(server) resp = {} # type: Dict[str, Any] if 'command' not in data: resp = {'error': "No command found in request"} else: command = data['command'] if not isinstance(command, str): resp = {'error': "Command is not a string"} else: command = data.pop('command') try: resp = self.run_command(command, data) except Exception: # If we are crashing, report the crash to the client tb = traceback.format_exception( *sys.exc_info()) resp = { 'error': "Daemon crashed!\n" + "".join(tb) } resp.update(self._response_metadata()) server.write(json.dumps(resp).encode('utf8')) raise try: resp.update(self._response_metadata()) server.write(json.dumps(resp).encode('utf8')) except OSError: pass # Maybe the client hung up if command == 'stop': reset_global_state() sys.exit(0) finally: # If the final command is something other than a clean # stop, remove the status file. (We can't just # simplify the logic and always remove the file, since # that could cause us to remove a future server's # status file.) if command != 'stop': os.unlink(self.status_file) try: server.cleanup() # try to remove the socket dir on Linux except OSError: pass exc_info = sys.exc_info() if exc_info[0] and exc_info[0] is not SystemExit: traceback.print_exception(*exc_info)
def serve(self) -> None: """Serve requests, synchronously (no thread or fork).""" command = None try: server = IPCServer(CONNECTION_NAME, self.timeout) with open(self.status_file, 'w') as f: json.dump({'pid': os.getpid(), 'connection_name': server.connection_name}, f) f.write('\n') # I like my JSON with a trailing newline while True: with server: data = receive(server) resp = {} # type: Dict[str, Any] if 'command' not in data: resp = {'error': "No command found in request"} else: command = data['command'] if not isinstance(command, str): resp = {'error': "Command is not a string"} else: command = data.pop('command') try: resp = self.run_command(command, data) except Exception: # If we are crashing, report the crash to the client tb = traceback.format_exception(*sys.exc_info()) resp = {'error': "Daemon crashed!\n" + "".join(tb)} resp.update(self._response_metadata()) server.write(json.dumps(resp).encode('utf8')) raise try: resp.update(self._response_metadata()) server.write(json.dumps(resp).encode('utf8')) except OSError: pass # Maybe the client hung up if command == 'stop': reset_global_state() sys.exit(0) finally: # If the final command is something other than a clean # stop, remove the status file. (We can't just # simplify the logic and always remove the file, since # that could cause us to remove a future server's # status file.) if command != 'stop': os.unlink(self.status_file) try: server.cleanup() # try to remove the socket dir on Linux except OSError: pass exc_info = sys.exc_info() if exc_info[0] and exc_info[0] is not SystemExit: traceback.print_exception(*exc_info)