diff options
author | Tomás Touceda <chiiph@leap.se> | 2013-07-26 10:45:29 -0300 |
---|---|---|
committer | Tomás Touceda <chiiph@leap.se> | 2013-07-26 10:45:29 -0300 |
commit | 66d02033fe4f38de04aa174b8e7b35bbabe3c678 (patch) | |
tree | c6740a2406adada67ad65c72c66b4727f0221239 /src/leap/common/events/__init__.py | |
parent | 8b5e745eb274be5b38c99d1b6121521ec2023475 (diff) | |
parent | b006c2c56fe0b83a3baf6a10a1e7dbe196051b8d (diff) |
Merge branch 'release-0.2.7'
Diffstat (limited to 'src/leap/common/events/__init__.py')
-rw-r--r-- | src/leap/common/events/__init__.py | 109 |
1 files changed, 93 insertions, 16 deletions
diff --git a/src/leap/common/events/__init__.py b/src/leap/common/events/__init__.py index 12416e4..6eaf3d4 100644 --- a/src/leap/common/events/__init__.py +++ b/src/leap/common/events/__init__.py @@ -16,7 +16,58 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. """ -An events mechanism that allows for signaling of events between components. +This is an events mechanism that uses a server to allow for signaling of +events between clients. + +Application components should use the interface available in this file to +register callbacks to be executed upon receiving specific signals, and to send +signals to other components. + +To register a callback to be executed when a specific event is signaled, use +leap.common.events.register(): + +>>> from leap.common.events import register +>>> from leap.common.events.proto import CLIENT_UID +>>> register(CLIENT_UID, lambda req: do_something(req)) + +To signal an event, use leap.common.events.signal(): + +>>> from leap.common.events import signal +>>> from leap.common.events.proto import CLIENT_UID +>>> signal(CLIENT_UID) + + +NOTE ABOUT SYNC/ASYNC REQUESTS: + +Clients always communicate with the server, and never between themselves. +When a client registers a callback for an event, the callback is saved locally +in the client and the server stores the client socket port in a list +associated with that event. When a client signals an event, the server +forwards the signal to all registered client ports, and then each client +executes its callbacks associated with that event locally. + +Each RPC call from a client to the server is followed by a response from the +server to the client. Calls to register() and signal() (and all other RPC +calls) can be synchronous or asynchronous meaning if they will or not wait for +the server's response before returning. + +This mechanism was built on top of protobuf.socketrpc, and because of this RPC +calls are made synchronous or asynchronous in the following way: + + * If RPC calls receive a parameter called `reqcbk`, then the call is made + asynchronous. That means that: + + - an eventual `timeout` parameter is not used, + - the call returns immediatelly with value None, and + - the `reqcbk` callback is executed asynchronously upon the arrival of + a response from the server. + + * Otherwise, if the `reqcbk` parameter is None, then the call is made in a + synchronous manner: + + - if a response from server arrives within `timeout` milliseconds, the + RPC call returns it; + - otherwise, the call returns None. """ import logging @@ -26,7 +77,7 @@ import socket from leap.common.events import ( events_pb2 as proto, server, - component, + client, daemon, ) @@ -54,9 +105,8 @@ def register(signal, callback, uid=None, replace=False, reqcbk=None, :param replace: should an existent callback with same uid be replaced? :type replace: bool :param reqcbk: a callback to be called when a response from server is - received - :type reqcbk: function - callback(leap.common.events.events_pb2.EventResponse) + received + :type reqcbk: function(leap.common.events.events_pb2.EventResponse) :param timeout: the timeout for synch calls :type timeout: int @@ -64,7 +114,7 @@ def register(signal, callback, uid=None, replace=False, reqcbk=None, calls. :rtype: leap.common.events.events_pb2.EventsResponse or None """ - return component.register(signal, callback, uid, replace, reqcbk, timeout) + return client.register(signal, callback, uid, replace, reqcbk, timeout) def unregister(signal, uid=None, reqcbk=None, timeout=1000): @@ -79,17 +129,16 @@ def unregister(signal, uid=None, reqcbk=None, timeout=1000): :param uid: a unique id for the callback :type uid: int :param reqcbk: a callback to be called when a response from server is - received - :type reqcbk: function - callback(leap.common.events.events_pb2.EventResponse) + received + :type reqcbk: function(proto.UnregisterRequest, proto.EventResponse) :param timeout: the timeout for synch calls :type timeout: int :return: the response from server for synch calls or nothing for asynch - calls. + calls. :rtype: leap.common.events.events_pb2.EventsResponse or None """ - return component.unregister(signal, uid, reqcbk, timeout) + return client.unregister(signal, uid, reqcbk, timeout) def signal(signal, content="", mac_method="", mac="", reqcbk=None, @@ -112,14 +161,42 @@ def signal(signal, content="", mac_method="", mac="", reqcbk=None, :param mac: the content of the auth mac :type mac: str :param reqcbk: a callback to be called when a response from server is - received - :type reqcbk: function - callback(leap.common.events.events_pb2.EventResponse) + received + :type reqcbk: function(proto.SignalRequest, proto.EventResponse) :param timeout: the timeout for synch calls :type timeout: int :return: the response from server for synch calls or nothing for asynch - calls. + calls. :rtype: leap.common.events.events_pb2.EventsResponse or None """ - return component.signal(signal, content, mac_method, mac, reqcbk, timeout) + return client.signal(signal, content, mac_method, mac, reqcbk, timeout) + +def ping_client(port, reqcbk=None, timeout=1000): + """ + Ping a client running in C{port}. + + :param port: the port in which the client should be listening + :type port: int + :param reqcbk: a callback to be called when a response from client is + received + :type reqcbk: function(proto.PingRequest, proto.EventResponse) + :param timeout: the timeout for synch calls + :type timeout: int + """ + return client.ping(port, reqcbk=reqcbk, timeout=timeout) + + +def ping_server(port=server.SERVER_PORT, reqcbk=None, timeout=1000): + """ + Ping the server. + + :param port: the port in which server should be listening + :type port: int + :param reqcbk: a callback to be called when a response from server is + received + :type reqcbk: function(proto.PingRequest, proto.EventResponse) + :param timeout: the timeout for synch calls + :type timeout: int + """ + return server.ping(port, reqcbk=reqcbk, timeout=timeout) |