Loading sjrpc/client/simple.py +5 −5 Original line number Diff line number Diff line Loading @@ -22,7 +22,7 @@ class SimpleRpcClient(ConnectionManager): self._on_disconnect = on_disconnect self._connection = connection self._connection.set_handler(default_handler) self.register(self._connection) self.register(self._connection.get_fd(), self._handle_event) @classmethod def from_addr(cls, addr, port, enable_ssl=False, cert=None, timeout=None, Loading Loading @@ -79,8 +79,8 @@ class SimpleRpcClient(ConnectionManager): super(SimpleRpcClient, self).shutdown() self._connection.shutdown(self._on_disconnect) def handle_event(self, fd, event): if event & select.EPOLLIN: def _handle_event(self, fd, events): if events & select.EPOLLIN: # Data are ready to be readed on socket try: self._connection.receive() Loading @@ -89,7 +89,7 @@ class SimpleRpcClient(ConnectionManager): 'fd/%s: %s', fd, err) self.shutdown() if event & select.EPOLLOUT: if events & select.EPOLLOUT: # Data are ready to be written on socket try: self._connection.send() Loading @@ -98,7 +98,7 @@ class SimpleRpcClient(ConnectionManager): 'fd/%s: %s', fd, err) self.shutdown() if event & select.EPOLLHUP: if events & select.EPOLLHUP: logging.debug('Socket HUP fd/%s', fd) self.shutdown() Loading sjrpc/core/connectionmanagers.py +34 −17 Original line number Diff line number Diff line Loading @@ -22,16 +22,35 @@ class ConnectionManager(object): self._running = True self._received_msg = {} self._wait_groups = {} self._poll_callbacks = {} def register(self, connection): def register(self, fd, callback, *args, **kwargs): ''' Register a :class:`RpcConnection` object on this manager. Register an fd on the poll object with the specified callback. The callback will be called each time poller drop an event for the specified fd. Extra args will be passed to the callback after fd and events. :param connection: the instance of :class:`RpcConnection` to register :type param: instance of :class:`RpcConnection` :param fd: the fd to register :param callback: the callable to use on event :param *args, **kwargs: extra arguments passed to the callback ''' self._poll.register(connection.get_fd(), ConnectionManager.MASK_NORMAL) if hasattr(fd, 'fileno'): fd = fd.fileno() self._poll_callbacks[fd] = {'func': callback, 'extra': args, 'kwextra': kwargs} self._poll.register(fd, ConnectionManager.MASK_NORMAL) def unregister(self, fd): ''' Unregister the specified fd from the manager. :param fd: the fd to unregister. ''' self._poll.unregister(fd) del self._poll_callbacks[fd] def is_running(self): return self._running Loading @@ -49,7 +68,9 @@ class ConnectionManager(object): pass else: for fd, event in events: self.handle_event(fd, event) if fd in self._poll_callbacks: cb = self._poll_callbacks[fd] cb['func'](fd, event, *cb['extra'], **cb['kwextra']) def start(self, daemonize=False): ''' Loading Loading @@ -167,29 +188,25 @@ class ConnectionManager(object): self._running = False def data_to_write(self, connection): def data_to_write(self, fd): ''' Method called by a connection to inform the manager that it have data to send. :param connection: the :class:`RpcConnection` object which inform the manager :param connection: the fd which have data to write ''' fd = connection.get_fd() if fd is not None: self._poll.modify(fd, ConnectionManager.MASK_WRITABLE) def nothing_to_write(self, connection): def nothing_to_write(self, fd): ''' Method called by a connection to inform the manager that it have no more data to send. :param connection: the :class:`RpcConnection` object which inform the manager :param fd: the fd which have no more data to write ''' fd = connection.get_fd() if fd is not None: self._poll.modify(fd, ConnectionManager.MASK_NORMAL) Loading sjrpc/core/rpcconnection.py +2 −2 Original line number Diff line number Diff line Loading @@ -115,7 +115,7 @@ class RpcConnection(object): with self._outbound_buffer: if not len(self._outbound_buffer): self._manager.nothing_to_write(self) self._manager.nothing_to_write(self.get_fd()) def receive(self): ''' Loading Loading @@ -183,7 +183,7 @@ class RpcConnection(object): size = struct.pack('!L', len(json_msg)) with self._outbound_buffer: self._outbound_buffer.push(size + json_msg) self._manager.data_to_write(self) self._manager.data_to_write(self.get_fd()) def _send_call(self, method_name, *args, **kwargs): ''' Loading sjrpc/server/simple.py +45 −49 Original line number Diff line number Diff line Loading @@ -22,7 +22,7 @@ class SimpleRpcServer(ConnectionManager): super(SimpleRpcServer, self).__init__() sock.setblocking(False) self._listening_sock = sock self._poll.register(sock) self.register(sock, self._handle_master_event) self._clients = {} self._default_handler = default_handler self._on_disconnect = on_disconnect Loading @@ -30,10 +30,6 @@ class SimpleRpcServer(ConnectionManager): def _accept_connection(self): return self._listening_sock.accept() def register(self, connection): super(SimpleRpcServer, self).register(connection) self._clients[connection.get_fd()] = connection def shutdown(self): super(SimpleRpcServer, self).shutdown() time.sleep(ConnectionManager.POLL_TIMEOUT) Loading @@ -44,7 +40,7 @@ class SimpleRpcServer(ConnectionManager): def shutdown_client(self, fd): conn = self._clients.get(fd) try: self._poll.unregister(fd) self.unregister(fd) except IOError: pass if fd is not None: Loading @@ -58,22 +54,22 @@ class SimpleRpcServer(ConnectionManager): def all_connections(self): return set(self._clients.values()) def handle_event(self, fd, event): if fd == self._listening_sock.fileno(): def _handle_master_event(self, fd, events): # Event concerns the listening socket: if event & select.EPOLLIN: if events & select.EPOLLIN: accepted = self._accept_connection() if accepted is not None: sock, address = accepted sock.setblocking(False) connection = RpcConnection(sock, self, handler=self._default_handler) self.register(connection) else: # Event concerns a client socket: self.register(connection.get_fd(), self._handle_client_event) self._clients[connection.get_fd()] = connection def _handle_client_event(self, fd, events): connection = self._clients[fd] if event & select.EPOLLIN: if events & select.EPOLLIN: # Data are ready to be readed on socket try: connection.receive() Loading @@ -86,7 +82,7 @@ class SimpleRpcServer(ConnectionManager): 'fd/%s: %s', fd, err) self.shutdown_client(fd) if event & select.EPOLLOUT: if events & select.EPOLLOUT: # Data are ready to be written on socket try: connection.send() Loading @@ -99,7 +95,7 @@ class SimpleRpcServer(ConnectionManager): 'fd/%s: %s', fd, err) self.shutdown_client(fd) if event & select.EPOLLHUP: if events & select.EPOLLHUP: logging.debug('Socket HUP fd/%s', fd) self.shutdown_client(fd) Loading Loading
sjrpc/client/simple.py +5 −5 Original line number Diff line number Diff line Loading @@ -22,7 +22,7 @@ class SimpleRpcClient(ConnectionManager): self._on_disconnect = on_disconnect self._connection = connection self._connection.set_handler(default_handler) self.register(self._connection) self.register(self._connection.get_fd(), self._handle_event) @classmethod def from_addr(cls, addr, port, enable_ssl=False, cert=None, timeout=None, Loading Loading @@ -79,8 +79,8 @@ class SimpleRpcClient(ConnectionManager): super(SimpleRpcClient, self).shutdown() self._connection.shutdown(self._on_disconnect) def handle_event(self, fd, event): if event & select.EPOLLIN: def _handle_event(self, fd, events): if events & select.EPOLLIN: # Data are ready to be readed on socket try: self._connection.receive() Loading @@ -89,7 +89,7 @@ class SimpleRpcClient(ConnectionManager): 'fd/%s: %s', fd, err) self.shutdown() if event & select.EPOLLOUT: if events & select.EPOLLOUT: # Data are ready to be written on socket try: self._connection.send() Loading @@ -98,7 +98,7 @@ class SimpleRpcClient(ConnectionManager): 'fd/%s: %s', fd, err) self.shutdown() if event & select.EPOLLHUP: if events & select.EPOLLHUP: logging.debug('Socket HUP fd/%s', fd) self.shutdown() Loading
sjrpc/core/connectionmanagers.py +34 −17 Original line number Diff line number Diff line Loading @@ -22,16 +22,35 @@ class ConnectionManager(object): self._running = True self._received_msg = {} self._wait_groups = {} self._poll_callbacks = {} def register(self, connection): def register(self, fd, callback, *args, **kwargs): ''' Register a :class:`RpcConnection` object on this manager. Register an fd on the poll object with the specified callback. The callback will be called each time poller drop an event for the specified fd. Extra args will be passed to the callback after fd and events. :param connection: the instance of :class:`RpcConnection` to register :type param: instance of :class:`RpcConnection` :param fd: the fd to register :param callback: the callable to use on event :param *args, **kwargs: extra arguments passed to the callback ''' self._poll.register(connection.get_fd(), ConnectionManager.MASK_NORMAL) if hasattr(fd, 'fileno'): fd = fd.fileno() self._poll_callbacks[fd] = {'func': callback, 'extra': args, 'kwextra': kwargs} self._poll.register(fd, ConnectionManager.MASK_NORMAL) def unregister(self, fd): ''' Unregister the specified fd from the manager. :param fd: the fd to unregister. ''' self._poll.unregister(fd) del self._poll_callbacks[fd] def is_running(self): return self._running Loading @@ -49,7 +68,9 @@ class ConnectionManager(object): pass else: for fd, event in events: self.handle_event(fd, event) if fd in self._poll_callbacks: cb = self._poll_callbacks[fd] cb['func'](fd, event, *cb['extra'], **cb['kwextra']) def start(self, daemonize=False): ''' Loading Loading @@ -167,29 +188,25 @@ class ConnectionManager(object): self._running = False def data_to_write(self, connection): def data_to_write(self, fd): ''' Method called by a connection to inform the manager that it have data to send. :param connection: the :class:`RpcConnection` object which inform the manager :param connection: the fd which have data to write ''' fd = connection.get_fd() if fd is not None: self._poll.modify(fd, ConnectionManager.MASK_WRITABLE) def nothing_to_write(self, connection): def nothing_to_write(self, fd): ''' Method called by a connection to inform the manager that it have no more data to send. :param connection: the :class:`RpcConnection` object which inform the manager :param fd: the fd which have no more data to write ''' fd = connection.get_fd() if fd is not None: self._poll.modify(fd, ConnectionManager.MASK_NORMAL) Loading
sjrpc/core/rpcconnection.py +2 −2 Original line number Diff line number Diff line Loading @@ -115,7 +115,7 @@ class RpcConnection(object): with self._outbound_buffer: if not len(self._outbound_buffer): self._manager.nothing_to_write(self) self._manager.nothing_to_write(self.get_fd()) def receive(self): ''' Loading Loading @@ -183,7 +183,7 @@ class RpcConnection(object): size = struct.pack('!L', len(json_msg)) with self._outbound_buffer: self._outbound_buffer.push(size + json_msg) self._manager.data_to_write(self) self._manager.data_to_write(self.get_fd()) def _send_call(self, method_name, *args, **kwargs): ''' Loading
sjrpc/server/simple.py +45 −49 Original line number Diff line number Diff line Loading @@ -22,7 +22,7 @@ class SimpleRpcServer(ConnectionManager): super(SimpleRpcServer, self).__init__() sock.setblocking(False) self._listening_sock = sock self._poll.register(sock) self.register(sock, self._handle_master_event) self._clients = {} self._default_handler = default_handler self._on_disconnect = on_disconnect Loading @@ -30,10 +30,6 @@ class SimpleRpcServer(ConnectionManager): def _accept_connection(self): return self._listening_sock.accept() def register(self, connection): super(SimpleRpcServer, self).register(connection) self._clients[connection.get_fd()] = connection def shutdown(self): super(SimpleRpcServer, self).shutdown() time.sleep(ConnectionManager.POLL_TIMEOUT) Loading @@ -44,7 +40,7 @@ class SimpleRpcServer(ConnectionManager): def shutdown_client(self, fd): conn = self._clients.get(fd) try: self._poll.unregister(fd) self.unregister(fd) except IOError: pass if fd is not None: Loading @@ -58,22 +54,22 @@ class SimpleRpcServer(ConnectionManager): def all_connections(self): return set(self._clients.values()) def handle_event(self, fd, event): if fd == self._listening_sock.fileno(): def _handle_master_event(self, fd, events): # Event concerns the listening socket: if event & select.EPOLLIN: if events & select.EPOLLIN: accepted = self._accept_connection() if accepted is not None: sock, address = accepted sock.setblocking(False) connection = RpcConnection(sock, self, handler=self._default_handler) self.register(connection) else: # Event concerns a client socket: self.register(connection.get_fd(), self._handle_client_event) self._clients[connection.get_fd()] = connection def _handle_client_event(self, fd, events): connection = self._clients[fd] if event & select.EPOLLIN: if events & select.EPOLLIN: # Data are ready to be readed on socket try: connection.receive() Loading @@ -86,7 +82,7 @@ class SimpleRpcServer(ConnectionManager): 'fd/%s: %s', fd, err) self.shutdown_client(fd) if event & select.EPOLLOUT: if events & select.EPOLLOUT: # Data are ready to be written on socket try: connection.send() Loading @@ -99,7 +95,7 @@ class SimpleRpcServer(ConnectionManager): 'fd/%s: %s', fd, err) self.shutdown_client(fd) if event & select.EPOLLHUP: if events & select.EPOLLHUP: logging.debug('Socket HUP fd/%s', fd) self.shutdown_client(fd) Loading