[bug] avoid the events server to block twistd daemon
[leap_pycommon.git] / src / leap / common / events / server.py
1 # -*- coding: utf-8 -*-
2 # server.py
3 # Copyright (C) 2013 LEAP
4 #
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation, either version 3 of the License, or
8 # (at your option) any later version.
9 #
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
14 #
15 # You should have received a copy of the GNU General Public License
16 # along with this program. If not, see <http://www.gnu.org/licenses/>.
17 """
18 The server for the events mechanism.
19 """
20 import logging
21 import platform
22
23 from leap.common.zmq_utils import zmq_has_curve
24
25 from leap.common.events.zmq_components import TxZmqServerComponent
26
27 import txzmq
28
29
30 if zmq_has_curve() or platform.system() == "Windows":
31     # Windows doesn't have ipc sockets, we need to use always tcp
32     EMIT_ADDR = "tcp://127.0.0.1:9000"
33     REG_ADDR = "tcp://127.0.0.1:9001"
34 else:
35     EMIT_ADDR = "ipc:///tmp/leap.common.events.socket.0"
36     REG_ADDR = "ipc:///tmp/leap.common.events.socket.1"
37
38 logger = logging.getLogger(__name__)
39
40
41 def ensure_server(emit_addr=EMIT_ADDR, reg_addr=REG_ADDR):
42     """
43     Make sure the server is running in the given addresses.
44
45     :param emit_addr: The address in which to receive events from clients.
46     :type emit_addr: str
47     :param reg_addr: The address to which publish events to clients.
48     :type reg_addr: str
49
50     :return: an events server instance
51     :rtype: EventsServer
52     """
53     _server = EventsServer(emit_addr, reg_addr)
54     return _server
55
56
57 class EventsServer(TxZmqServerComponent):
58     """
59     An events server that listens for events in one address and publishes those
60     events in another address.
61     """
62
63     def __init__(self, emit_addr, reg_addr):
64         """
65         Initialize the events server.
66
67         :param emit_addr: The address in which to receive events from clients.
68         :type emit_addr: str
69         :param reg_addr: The address to which publish events to clients.
70         :type reg_addr: str
71         """
72         TxZmqServerComponent.__init__(self)
73         # bind PULL and PUB sockets
74         self._pull, self.pull_port = self._zmq_bind(
75             txzmq.ZmqPullConnection, emit_addr)
76         self._pub, self.pub_port = self._zmq_bind(
77             txzmq.ZmqPubConnection, reg_addr)
78         # set a handler for arriving messages
79         self._pull.onPull = self._onPull
80
81     def _onPull(self, message):
82         """
83         Callback executed when a message is pulled from a client.
84
85         :param message: The message sent by the client.
86         :type message: str
87         """
88         event, content = message[0].split(b"\0", 1)
89         logger.debug("Publishing event: %s" % event)
90         self._pub.publish(content, tag=event)