def listen(address): cnx = Client(address) while True: try: args, num_fds = cnx.recv() except EOFError: break fds = dict((idx, _multiprocessing.recvfd(cnx.fileno())) for idx in range(num_fds)) proc = _PyPopen(*args, _fd_map=fds) stdout, stderr = proc.communicate() retcode = proc.poll() cnx.send((retcode, stdout, stderr))
def listen(address): cnx = Client(address) while True: try: args, num_fds = cnx.recv() except EOFError: break fds = dict( (idx, _multiprocessing.recvfd(cnx.fileno())) for idx in range(num_fds) ) proc = _PyPopen(*args, _fd_map=fds) stdout, stderr = proc.communicate() retcode = proc.poll() cnx.send((retcode, stdout, stderr))
class Client(object): """Send a command to a listener process. Args: address (tuple/object): The address to be used by the bound socket or named pipe (EX: "IP Address", Port) family (socket.family/str)[None]: Type of socket or named pipe to use (EX: 'AF_INET', 'AF_UNIX', 'AF_PIPE') authkey (bytes)[None]: The secret key (password) for an HMAC-based authentication challenge. No auth if None Raises: AuthenticationError: If authkey is given and authentication fails """ MY_IP = MY_IP get_local_addrs = staticmethod(get_local_addrs) def __init__(self, address, family=None, authkey=None): """Create the client connection to another process. Args: address (tuple/object): The address to be used by the bound socket or named pipe (EX: "IP Address", Port) family (socket.family/str)[None]: Type of socket or named pipe to use (EX: 'AF_INET', 'AF_UNIX', 'AF_PIPE') authkey (bytes)[None]: The secret key (password) for an HMAC-based authentication challenge. No auth if None Raises: AuthenticationError: If authkey is given and authentication fails """ if isinstance(authkey, str): authkey = authkey.encode('utf-8') # Connection settings self.address = address self.family = family # self.authkey = authkey # Probably not good to save the authkey self.client = None self.connect(address, family, authkey) def connect(self, address=None, family=None, authkey=None): """Connect the multiprocessing client.""" if address is not None: self.address = address if family is not None: self.family = family self.client = MpClient(self.address, family=self.family, authkey=authkey) # Why is this a function!? F def msg_handler(self, cmd): """Handle the response after sending a command. This is where you would receive an ack or nack from the socket. Args: cmd (object): Command that was sent. Returns: success (bool): True if the message sent successfully! """ return True @staticmethod def recv_socket(sock): """Receive data from the connection.""" return sock.recv() @staticmethod def send_socket(sock, data): """Send data to the connection.""" sock.send(data) def send(self, cmd): """Send the data to the server.""" self.send_socket(self.client, cmd) return self.msg_handler(cmd) def recv(self): """Receive data from the server.""" return self.recv_socket(self.client) def poll(self, timeout=0.0): """Whether there is any input available to be read""" return self.client.poll(timeout=timeout) @property def closed(self): """True if the connection is closed""" return self.client.closed @property def readable(self): """True if the connection is readable""" return self.client.readable @property def writable(self): """True if the connection is writable""" return self.client.writable def fileno(self): """File descriptor or handle of the connection""" return self.client.fileno() def close(self): """Close the connection""" time.sleep(0.01) # Could be sending a message self.client.close() stop = close def __enter__(self): return self def __exit__(self, exc_type, exc_value, exc_tb): self.close() return False