summaryrefslogtreecommitdiff
path: root/src/leap/common/events/server.py
diff options
context:
space:
mode:
authordrebs <drebs@leap.se>2013-07-24 16:26:52 -0300
committerdrebs <drebs@leap.se>2013-07-24 16:55:20 -0300
commitb7c74e4f293d0e611ea038e04022fbe700a8cb42 (patch)
treeb121ebc957b36584fdab077b3071b183776ab293 /src/leap/common/events/server.py
parent1f1412f3c31dfba10135ceae4641313ee48318c8 (diff)
Trying to init events server raises when given port is not free.
* Also fix and improve some tests.
Diffstat (limited to 'src/leap/common/events/server.py')
-rw-r--r--src/leap/common/events/server.py60
1 files changed, 58 insertions, 2 deletions
diff --git a/src/leap/common/events/server.py b/src/leap/common/events/server.py
index 8a0d4e5..daccc61 100644
--- a/src/leap/common/events/server.py
+++ b/src/leap/common/events/server.py
@@ -48,6 +48,13 @@ SERVER_PORT = 8090
registered_clients = {}
+class PortAlreadyTaken(Exception):
+ """
+ Raised when trying to open a server in a port that is already taken.
+ """
+ pass
+
+
def ensure_server(port=SERVER_PORT):
"""
Make sure the server is running on the given port.
@@ -60,18 +67,51 @@ def ensure_server(port=SERVER_PORT):
:return: the daemon instance or nothing
:rtype: EventsServerDaemon or None
+
+ :raise PortAlreadyTaken: Raised if C{port} is already taken by something
+ that is not an events server.
"""
try:
+ # check if port is available
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('localhost', port))
s.close()
- logger.info('Server is already running on port %d.', port)
- return None
+ # port is taken, check if there's a server running there
+ response = ping(port)
+ if response is not None and response.status == proto.EventResponse.OK:
+ logger.info('A server is already running on port %d.', port)
+ return None
+ # port is taken, and not by an events server
+ logger.info('Port %d is taken by something not an events server.', port)
+ raise PortAlreadyTaken(port)
except socket.error:
+ # port is available, run a server
logger.info('Launching server on port %d.', port)
return EventsServerDaemon.ensure(port)
+def ping(port=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
+ callback(leap.common.events.events_pb2.EventResponse)
+ :param timeout: the timeout for synch calls
+ :type timeout: int
+ """
+ request = proto.PingRequest()
+ service = RpcService(
+ proto.EventsServerService_Stub,
+ port,
+ 'localhost')
+ logger.info("Pinging server in port %d..." % port)
+ return service.ping(request, callback=reqcbk, timeout=timeout)
+
+
class EventsServerService(proto.EventsServerService):
"""
Service for receiving events in clients.
@@ -156,6 +196,22 @@ class EventsServerService(proto.EventsServerService):
response.status = proto.EventResponse.OK
done.run(response)
+ def ping(self, controller, request, done):
+ """
+ Reply to a ping request.
+
+ :param controller: used to mediate a single method call
+ :type controller: protobuf.socketrpc.controller.SocketRpcController
+ :param request: the request received from the client
+ :type request: leap.common.events.events_pb2.RegisterRequest
+ :param done: callback to be called when done
+ :type done: protobuf.socketrpc.server.Callback
+ """
+ logger.info("Received ping request, sending response.")
+ response = proto.EventResponse()
+ response.status = proto.EventResponse.OK
+ done.run(response)
+
class EventsServerDaemon(daemon.EventsSingletonDaemon):
"""