Loading sjrpc/__init__.py +4 −8 Original line number Diff line number Diff line ''' This module implements a Remote Procedure Call system using socket objects as transport. The main feature of this RPC is to be bidirectionnal: both client and server can serve remote procedure for its peer. """ This module implements a Remote Procedure Call system using socket objects as transport. The main feature of this RPC is to be bidirectionnal: both client and server can serve remote procedure for its peer. Features: Loading @@ -16,7 +13,6 @@ The library is separated into three parts: * **core** package contains all common classes. * **server** package contains all the server side related stuff. * **utils** package contains some helpers used in previous libraries. ''' """ __version__ = '18~dev' sjrpc/core/__init__.py +3 −7 Original line number Diff line number Diff line ''' The **core** package contains all classes used by both client mode and server mode. """ The **core** package contains all classes used by both client mode and server mode. This packages export following function/classes: Loading @@ -14,8 +11,7 @@ This packages export following function/classes: * :class:`AsyncWatcher` which allow to make asynchronous calls. It also contains a sub-package containing protocols: :mod:`core.protocols`. ''' """ from __future__ import absolute_import Loading sjrpc/core/async.py +16 −23 Original line number Diff line number Diff line Loading @@ -6,8 +6,7 @@ from Queue import Queue, Empty class AsyncWatcher(object): ''' Asynchronous call watcher -- Handle asynchronous calls and responses. """ Asynchronous call watcher -- Handle asynchronous calls and responses. Usage example:: Loading @@ -15,18 +14,16 @@ class AsyncWatcher(object): >>> watcher.register(conn1, 'ping') >>> watcher.register(conn2, 'ping') >>> responses = watcher.wait() # Wait for all responses ''' """ def __init__(self): self._response_queue = Queue() self._expected_responses = {} def _get_in_queue(self, *args, **kwargs): ''' Get an item in response queue and return it with the time waited to its comming. Accept all arguments accepted by :meth:`Queue.get` ''' """ Get an item in response queue and return it with the time waited to its comming. Accept all arguments accepted by :meth:`Queue.get` """ start = datetime.datetime.now() item = self._response_queue.get(*args, **kwargs) dt = datetime.datetime.now() - start Loading @@ -39,27 +36,24 @@ class AsyncWatcher(object): @property def remains(self): ''' Remaining expected responses. ''' """ Remaining expected responses. """ return len(self._expected_responses) def register(self, rpc, method, *args, **kwargs): ''' Call specified method on specified rpc with specified arguments """ Call specified method on specified rpc with specified arguments and register the call on this object. :param rpc: the rpc on which made the call :param method: the rpc method to call :param \*args, \*\*kwargs: the arguments to pass to the rpc method ''' """ msg_id = rpc.async_call(self._response_queue, method, *args, **kwargs) self._expected_responses[msg_id] = kwargs.pop('_data', None) # Data are stored directly on the AsyncWatcher instead of RpcProtocol. def wait(self, timeout=None, max_wait=None, raise_timeout=False): ''' Wait responses for calls registered on this :class:`AsyncWatcher` """ Wait responses for calls registered on this :class:`AsyncWatcher` instance and return them. :param timeout: timeout value or None to disable timeout (default: None) Loading @@ -76,19 +70,18 @@ class AsyncWatcher(object): >>> process_speedy(msgs[0]) >>> for msg in watcher.wait(timeout=60): >>> process(msg) ''' """ return list(self.iter(timeout, max_wait, raise_timeout)) def iter(self, timeout=None, max_wait=None, raise_timeout=False): ''' Work like :meth:`AsyncWatcher.wait` but return an iterable, instead of a list object. """ Work like :meth:`AsyncWatcher.wait` but return an iterable, instead of a list object. .. note:: Responses are yielded by the iterable when they are received, so you can start the processing of response before receiving all. ''' """ while self.remains: try: Loading sjrpc/core/exceptions.py +15 −21 Original line number Diff line number Diff line """ Contains sjRpc exceptions. """ ''' Contains sjRpc exceptions. ''' class RpcError(Exception): ''' Exception raised by caller when an error occurs while execution of remote procedure call. ''' """ Exception raised by caller when an error occurs while execution of the remote procedure call. """ def __init__(self, exception, message): self.exception = exception Loading @@ -20,29 +18,25 @@ class RpcError(Exception): class RpcConnectionError(Exception): ''' Base class for RpcConnection errors. ''' """ Base class for RpcConnection errors. """ class SocketError(RpcConnectionError): ''' Exception used internally to raise a socket fault. ''' """ Exception used internally to raise a socket fault. """ class NoFreeLabelError(RpcConnectionError): ''' Exception raised when no more free labels are available for protocol """ Exception raised when no more free labels are available for protocol allocation. ''' """ class FallbackModeEnabledError(RpcConnectionError): ''' Exception raised when a feature which is not compatible with fallback mode is used. ''' """ Exception raised when a feature which is not compatible with fallback mode is used. """ sjrpc/core/protocols/__init__.py +28 −38 Original line number Diff line number Diff line ''' Protocols can be binded on a specific label of a :class:`RpcConnection` (see `Multiplexing & protocols`_ for more informations). """ Protocols can be binded on a specific label of a :class:`RpcConnection` (see `Multiplexing & protocols`_ for more informations). Following protocols are provided with standard distribution of sjRpc, but you can create yours if you needs: Loading @@ -11,8 +9,7 @@ can create yours if you needs: through the sjRpc connection - :class:`VpnProtocol` (experimental): like :class:`TunnelProtocol` but work with a network interface instead of a socket. ''' """ from __future__ import absolute_import Loading @@ -20,9 +17,8 @@ import logging class Protocol(object): ''' Base class for all protocols. ''' """ Base class for all protocols. """ def __init__(self, connection, label, logger=None): self._connection = connection Loading @@ -35,54 +31,48 @@ class Protocol(object): @property def connection(self): ''' The :class:`~sjrpc.core.RpcConnection` instance which handle """ The :class:`~sjrpc.core.RpcConnection` instance which handle this protocol. ''' """ return self._connection @property def label(self): ''' The label binded to this protocol in the :class:`~sjrpc.core.RpcConnection` instance. ''' """ The label binded to this protocol in the :class:`~sjrpc.core.RpcConnection` instance. """ return self._label def send(self, payload): ''' Send a message through the sjRpc connection. ''' """ Send a message through the sjRpc connection. """ self._connection.send(self._label, payload) def start_message(self, payload_size): ''' Start a new incoming message receipt. By default, this method create """ Start a new incoming message receipt. By default, this method create a new empty buffer on self._incoming_buf variable. ''' """ self._incoming_buf = '' def feed(self, data): ''' Handle a chunk of data received from the tunnel. By default, this method append this chunk to the end of the incoming buffer created by default by :meth:`start_message` method. ''' """ Handle a chunk of data received from the tunnel. By default, this method append this chunk to the end of the incoming buffer created by default by :meth:`start_message` method. """ self._incoming_buf += data def end_of_message(self): ''' Signal the end of the currently received message. With default :meth:`start_message` and :meth:`feed` methods, it's a good place to implements the processing of the incoming message. ''' """ Signal the end of the currently received message. With default :meth:`start_message` and :meth:`feed` methods, it's a good place to implements the processing of the incoming message. """ pass def handle_control(self, payload): ''' Handle a control message received from the Rpc0. ''' """ Handle a control message received from the Rpc0. """ pass def shutdown(self): Loading Loading
sjrpc/__init__.py +4 −8 Original line number Diff line number Diff line ''' This module implements a Remote Procedure Call system using socket objects as transport. The main feature of this RPC is to be bidirectionnal: both client and server can serve remote procedure for its peer. """ This module implements a Remote Procedure Call system using socket objects as transport. The main feature of this RPC is to be bidirectionnal: both client and server can serve remote procedure for its peer. Features: Loading @@ -16,7 +13,6 @@ The library is separated into three parts: * **core** package contains all common classes. * **server** package contains all the server side related stuff. * **utils** package contains some helpers used in previous libraries. ''' """ __version__ = '18~dev'
sjrpc/core/__init__.py +3 −7 Original line number Diff line number Diff line ''' The **core** package contains all classes used by both client mode and server mode. """ The **core** package contains all classes used by both client mode and server mode. This packages export following function/classes: Loading @@ -14,8 +11,7 @@ This packages export following function/classes: * :class:`AsyncWatcher` which allow to make asynchronous calls. It also contains a sub-package containing protocols: :mod:`core.protocols`. ''' """ from __future__ import absolute_import Loading
sjrpc/core/async.py +16 −23 Original line number Diff line number Diff line Loading @@ -6,8 +6,7 @@ from Queue import Queue, Empty class AsyncWatcher(object): ''' Asynchronous call watcher -- Handle asynchronous calls and responses. """ Asynchronous call watcher -- Handle asynchronous calls and responses. Usage example:: Loading @@ -15,18 +14,16 @@ class AsyncWatcher(object): >>> watcher.register(conn1, 'ping') >>> watcher.register(conn2, 'ping') >>> responses = watcher.wait() # Wait for all responses ''' """ def __init__(self): self._response_queue = Queue() self._expected_responses = {} def _get_in_queue(self, *args, **kwargs): ''' Get an item in response queue and return it with the time waited to its comming. Accept all arguments accepted by :meth:`Queue.get` ''' """ Get an item in response queue and return it with the time waited to its comming. Accept all arguments accepted by :meth:`Queue.get` """ start = datetime.datetime.now() item = self._response_queue.get(*args, **kwargs) dt = datetime.datetime.now() - start Loading @@ -39,27 +36,24 @@ class AsyncWatcher(object): @property def remains(self): ''' Remaining expected responses. ''' """ Remaining expected responses. """ return len(self._expected_responses) def register(self, rpc, method, *args, **kwargs): ''' Call specified method on specified rpc with specified arguments """ Call specified method on specified rpc with specified arguments and register the call on this object. :param rpc: the rpc on which made the call :param method: the rpc method to call :param \*args, \*\*kwargs: the arguments to pass to the rpc method ''' """ msg_id = rpc.async_call(self._response_queue, method, *args, **kwargs) self._expected_responses[msg_id] = kwargs.pop('_data', None) # Data are stored directly on the AsyncWatcher instead of RpcProtocol. def wait(self, timeout=None, max_wait=None, raise_timeout=False): ''' Wait responses for calls registered on this :class:`AsyncWatcher` """ Wait responses for calls registered on this :class:`AsyncWatcher` instance and return them. :param timeout: timeout value or None to disable timeout (default: None) Loading @@ -76,19 +70,18 @@ class AsyncWatcher(object): >>> process_speedy(msgs[0]) >>> for msg in watcher.wait(timeout=60): >>> process(msg) ''' """ return list(self.iter(timeout, max_wait, raise_timeout)) def iter(self, timeout=None, max_wait=None, raise_timeout=False): ''' Work like :meth:`AsyncWatcher.wait` but return an iterable, instead of a list object. """ Work like :meth:`AsyncWatcher.wait` but return an iterable, instead of a list object. .. note:: Responses are yielded by the iterable when they are received, so you can start the processing of response before receiving all. ''' """ while self.remains: try: Loading
sjrpc/core/exceptions.py +15 −21 Original line number Diff line number Diff line """ Contains sjRpc exceptions. """ ''' Contains sjRpc exceptions. ''' class RpcError(Exception): ''' Exception raised by caller when an error occurs while execution of remote procedure call. ''' """ Exception raised by caller when an error occurs while execution of the remote procedure call. """ def __init__(self, exception, message): self.exception = exception Loading @@ -20,29 +18,25 @@ class RpcError(Exception): class RpcConnectionError(Exception): ''' Base class for RpcConnection errors. ''' """ Base class for RpcConnection errors. """ class SocketError(RpcConnectionError): ''' Exception used internally to raise a socket fault. ''' """ Exception used internally to raise a socket fault. """ class NoFreeLabelError(RpcConnectionError): ''' Exception raised when no more free labels are available for protocol """ Exception raised when no more free labels are available for protocol allocation. ''' """ class FallbackModeEnabledError(RpcConnectionError): ''' Exception raised when a feature which is not compatible with fallback mode is used. ''' """ Exception raised when a feature which is not compatible with fallback mode is used. """
sjrpc/core/protocols/__init__.py +28 −38 Original line number Diff line number Diff line ''' Protocols can be binded on a specific label of a :class:`RpcConnection` (see `Multiplexing & protocols`_ for more informations). """ Protocols can be binded on a specific label of a :class:`RpcConnection` (see `Multiplexing & protocols`_ for more informations). Following protocols are provided with standard distribution of sjRpc, but you can create yours if you needs: Loading @@ -11,8 +9,7 @@ can create yours if you needs: through the sjRpc connection - :class:`VpnProtocol` (experimental): like :class:`TunnelProtocol` but work with a network interface instead of a socket. ''' """ from __future__ import absolute_import Loading @@ -20,9 +17,8 @@ import logging class Protocol(object): ''' Base class for all protocols. ''' """ Base class for all protocols. """ def __init__(self, connection, label, logger=None): self._connection = connection Loading @@ -35,54 +31,48 @@ class Protocol(object): @property def connection(self): ''' The :class:`~sjrpc.core.RpcConnection` instance which handle """ The :class:`~sjrpc.core.RpcConnection` instance which handle this protocol. ''' """ return self._connection @property def label(self): ''' The label binded to this protocol in the :class:`~sjrpc.core.RpcConnection` instance. ''' """ The label binded to this protocol in the :class:`~sjrpc.core.RpcConnection` instance. """ return self._label def send(self, payload): ''' Send a message through the sjRpc connection. ''' """ Send a message through the sjRpc connection. """ self._connection.send(self._label, payload) def start_message(self, payload_size): ''' Start a new incoming message receipt. By default, this method create """ Start a new incoming message receipt. By default, this method create a new empty buffer on self._incoming_buf variable. ''' """ self._incoming_buf = '' def feed(self, data): ''' Handle a chunk of data received from the tunnel. By default, this method append this chunk to the end of the incoming buffer created by default by :meth:`start_message` method. ''' """ Handle a chunk of data received from the tunnel. By default, this method append this chunk to the end of the incoming buffer created by default by :meth:`start_message` method. """ self._incoming_buf += data def end_of_message(self): ''' Signal the end of the currently received message. With default :meth:`start_message` and :meth:`feed` methods, it's a good place to implements the processing of the incoming message. ''' """ Signal the end of the currently received message. With default :meth:`start_message` and :meth:`feed` methods, it's a good place to implements the processing of the incoming message. """ pass def handle_control(self, payload): ''' Handle a control message received from the Rpc0. ''' """ Handle a control message received from the Rpc0. """ pass def shutdown(self): Loading