def connect_thread(service=VoidService, config={}, remote_service=VoidService, remote_config={}): """starts an rpyc server on a new thread, bound to an arbitrary port, and connects to it over a socket. :param service: the local service to expose (defaults to Void) :param config: configuration dict :param remote_service: the remote service to expose (of the server; defaults to Void) :param remote_config: remote configuration dict (of the server) """ listener = socket.socket() listener.bind(("localhost", 0)) listener.listen(1) def server(listener=listener): with closing(listener): client = listener.accept()[0] conn = connect_stream(SocketStream(client), service=remote_service, config=remote_config) try: conn.serve_all() except KeyboardInterrupt: interrupt_main() spawn(server) host, port = listener.getsockname() return connect(host, port, service=service, config=config)
def __init__(self, *args, **kwargs): '''Initializes a ThreadPoolServer. In particular, instantiate the thread pool.''' # get the number of threads in the pool nbthreads = 20 if 'nbThreads' in kwargs: nbthreads = kwargs['nbThreads'] del kwargs['nbThreads'] # get the request batch size self.request_batch_size = 10 if 'requestBatchSize' in kwargs: self.request_batch_size = kwargs['requestBatchSize'] del kwargs['requestBatchSize'] # init the parent Server.__init__(self, *args, **kwargs) # a queue of connections having something to process self._active_connection_queue = Queue.Queue() # declare the pool as already active self.active = True # setup the thread pool for handling requests self.workers = [] for i in range(nbthreads): t = spawn(self._serve_clients) t.setName('Worker%i' % i) self.workers.append(t) # a polling object to be used be the polling thread self.poll_object = poll() # a dictionary fd -> connection self.fd_to_conn = {} # setup a thread for polling inactive connections self.polling_thread = spawn(self._poll_inactive_clients) self.polling_thread.setName('PollingThread')
def _listen(self): if self.active: return super(ThreadPoolServer, self)._listen() # setup the thread pool for handling requests self.workers = [] for i in range(self.nbthreads): t = spawn(self._serve_clients) t.setName('Worker%i' % i) self.workers.append(t) # setup a thread for polling inactive connections self.polling_thread = spawn(self._poll_inactive_clients) self.polling_thread.setName('PollingThread')
def serve_threaded(self, thread_count=10): # serving """Serves all requests and replies for as long as the connection is alive. CAVEAT: using non-immutable types that require a netref to be constructed to serve a request, or invoking anything else that performs a sync_request, may timeout due to the sync_request reply being received by another thread serving the connection. A more conventional approach where each client thread opens a new connection would allow `ThreadedServer` to naturally avoid such multiplexing issues and is the preferred approach for threading procedures that invoke sync_request. See issue #345 """ def _thread_target(): try: while True: self.serve(None) except (socket.error, select_error, IOError): if not self.closed: raise except EOFError: pass try: threads = [spawn(_thread_target) for _ in range(thread_count)] for thread in threads: thread.join() finally: self.close()
def connect_thread(service=VoidService, config={}, remote_service=VoidService, remote_config={}): """starts an rpyc server on a new thread, bound to an arbitrary port, and connects to it over a socket. :param service: the local service to expose (defaults to Void) :param config: configuration dict :param remote_service: the remote service to expose (of the server; defaults to Void) :param remote_config: remote configuration dict (of the server) """ listener = socket.socket() listener.bind(("localhost", 0)) listener.listen(1) remote_server = partial(_server, listener, remote_service, remote_config) spawn(remote_server) host, port = listener.getsockname() return connect(host, port, service=service, config=config)
def serve_threaded(self, thread_count=10): """Serves all requests and replies for as long as the connection is alive.""" def _thread_target(): try: while True: self.serve(None) except (socket.error, select_error, IOError): if not self.closed: raise except EOFError: pass try: threads = [spawn(_thread_target) for _ in range(thread_count)] for thread in threads: thread.join() finally: self.close()
def _accept_method(self, sock): spawn(self._authenticate_and_serve_client, sock)
def _register(self): if self.auto_register: self.auto_register = False spawn(self._bg_register)
def __init__(self, conn, callback=None): self._conn = conn self._active = True self._callback = callback self._thread = spawn(self._bg_server)
if has_stop: class Breakpoint(gdb.Breakpoint): def stop(self): return client.stop() return Breakpoint(*args, **kwargs) return gdb.Breakpoint(*args, **kwargs) def exposed_quit(self): """Terminate GDB.""" gdb.post_event(lambda: gdb.execute("quit")) if "expose_extra" in globals(): for name in expose_extra: if name in globals(): value = globals()[name] name = f"exposed_{name}" setattr(GdbService, name, value) spawn( ThreadedServer( service=GdbService(), socket_path=socket_path, protocol_config={ "allow_all_attrs": True, }, ).start )